Merge pull request #15155 from obsidiansystems/protocol-version-structs
worker-protocol: replace version bit-shifting with structs
This commit is contained in:
@@ -100,26 +100,26 @@ public:
|
||||
writeProtoTest(STEM, VERSION, VALUE); \
|
||||
}
|
||||
|
||||
#define VERSIONED_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE)
|
||||
#define VERSIONED_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, (VERSION), VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, (VERSION), VALUE)
|
||||
|
||||
#define VERSIONED_READ_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_json_read) \
|
||||
{ \
|
||||
readJsonTest(STEM, VALUE); \
|
||||
#define VERSIONED_READ_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, (VERSION), VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_json_read) \
|
||||
{ \
|
||||
readJsonTest(STEM, VALUE); \
|
||||
}
|
||||
|
||||
#define VERSIONED_WRITE_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_json_write) \
|
||||
{ \
|
||||
writeJsonTest(STEM, VALUE); \
|
||||
#define VERSIONED_WRITE_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, (VERSION), VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_json_write) \
|
||||
{ \
|
||||
writeJsonTest(STEM, VALUE); \
|
||||
}
|
||||
|
||||
#define VERSIONED_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE)
|
||||
#define VERSIONED_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, (VERSION), VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, (VERSION), VALUE)
|
||||
|
||||
} // namespace nix
|
||||
|
||||
@@ -25,7 +25,10 @@ struct ServeProtoTest : VersionedProtoTest<ServeProto, serveProtoDir>
|
||||
* For serializers that don't care about the minimum version, we
|
||||
* used the oldest one: 2.5.
|
||||
*/
|
||||
ServeProto::Version defaultVersion = 2 << 8 | 5;
|
||||
ServeProto::Version defaultVersion = {
|
||||
.major = 2,
|
||||
.minor = 5,
|
||||
};
|
||||
};
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
@@ -144,54 +147,77 @@ VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(ServeProtoTest, buildResult_2_2, "build-result-2.2", 2 << 8 | 2, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}}},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(ServeProtoTest, buildResult_2_3, "build-result-2.3", 2 << 8 | 3, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
.isNonDeterministic = true,
|
||||
}}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}},
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
buildResult_2_2,
|
||||
"build-result-2.2",
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 2,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}}},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest, buildResult_2_6, "build-result-2.6", 2 << 8 | 6, ({
|
||||
ServeProtoTest,
|
||||
buildResult_2_3,
|
||||
"build-result-2.3",
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 3,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
.isNonDeterministic = true,
|
||||
}}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}},
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
buildResult_2_6,
|
||||
"build-result-2.6",
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 6,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
@@ -260,7 +286,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
unkeyedValidPathInfo_2_3,
|
||||
"unkeyed-valid-path-info-2.3",
|
||||
2 << 8 | 3,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 3,
|
||||
}),
|
||||
(std::tuple<UnkeyedValidPathInfo, UnkeyedValidPathInfo>{
|
||||
({
|
||||
UnkeyedValidPathInfo info{std::string{defaultStoreDir}, Hash::dummy};
|
||||
@@ -286,7 +315,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
unkeyedValidPathInfo_2_4,
|
||||
"unkeyed-valid-path-info-2.4",
|
||||
2 << 8 | 4,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 4,
|
||||
}),
|
||||
(std::tuple<UnkeyedValidPathInfo, UnkeyedValidPathInfo>{
|
||||
({
|
||||
UnkeyedValidPathInfo info{
|
||||
@@ -340,7 +372,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_1,
|
||||
"build-options-2.1",
|
||||
2 << 8 | 1,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 1,
|
||||
}),
|
||||
(ServeProto::BuildOptions{
|
||||
.maxSilentTime = 5,
|
||||
.buildTimeout = 6,
|
||||
@@ -350,7 +385,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_2,
|
||||
"build-options-2.2",
|
||||
2 << 8 | 2,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 2,
|
||||
}),
|
||||
(ServeProto::BuildOptions{
|
||||
.maxSilentTime = 5,
|
||||
.buildTimeout = 6,
|
||||
@@ -361,7 +399,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_3,
|
||||
"build-options-2.3",
|
||||
2 << 8 | 3,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 3,
|
||||
}),
|
||||
(ServeProto::BuildOptions{
|
||||
.maxSilentTime = 5,
|
||||
.buildTimeout = 6,
|
||||
@@ -374,7 +415,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_7,
|
||||
"build-options-2.7",
|
||||
2 << 8 | 7,
|
||||
(ServeProto::Version{
|
||||
.major = 2,
|
||||
.minor = 7,
|
||||
}),
|
||||
(ServeProto::BuildOptions{
|
||||
.maxSilentTime = 5,
|
||||
.buildTimeout = 6,
|
||||
|
||||
@@ -25,7 +25,10 @@ struct WorkerProtoTest : VersionedProtoTest<WorkerProto, workerProtoDir>
|
||||
* For serializers that don't care about the minimum version, we
|
||||
* used the oldest one: 1.10.
|
||||
*/
|
||||
WorkerProto::Version defaultVersion = 1 << 8 | 10;
|
||||
WorkerProto::Version defaultVersion = {
|
||||
.major = 1,
|
||||
.minor = 10,
|
||||
};
|
||||
};
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
@@ -79,7 +82,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
derivedPath_1_29,
|
||||
"derived-path-1.29",
|
||||
1 << 8 | 29,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 29,
|
||||
}),
|
||||
(std::tuple<DerivedPath, DerivedPath, DerivedPath>{
|
||||
DerivedPath::Opaque{
|
||||
.path = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
@@ -104,7 +110,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
derivedPath_1_30,
|
||||
"derived-path-1.30",
|
||||
1 << 8 | 30,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 30,
|
||||
}),
|
||||
(std::tuple<DerivedPath, DerivedPath, DerivedPath, DerivedPath>{
|
||||
DerivedPath::Opaque{
|
||||
.path = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
@@ -197,26 +206,41 @@ VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(WorkerProtoTest, buildResult_1_27, "build-result-1.27", 1 << 8 | 27, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}}},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
buildResult_1_27,
|
||||
"build-result-1.27",
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 27,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
BuildResult{.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
}}},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_28, "build-result-1.28", 1 << 8 | 28, ({
|
||||
WorkerProtoTest,
|
||||
buildResult_1_28,
|
||||
"build-result-1.28",
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 28,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
@@ -262,7 +286,14 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_29, "build-result-1.29", 1 << 8 | 29, ({
|
||||
WorkerProtoTest,
|
||||
buildResult_1_29,
|
||||
"build-result-1.29",
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 29,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
@@ -321,7 +352,14 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_37, "build-result-1.37", 1 << 8 | 37, ({
|
||||
WorkerProtoTest,
|
||||
buildResult_1_37,
|
||||
"build-result-1.37",
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 37,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{{
|
||||
@@ -381,48 +419,59 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(WorkerProtoTest, keyedBuildResult_1_29, "keyed-build-result-1.29", 1 << 8 | 29, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<KeyedBuildResult, KeyedBuildResult /*, KeyedBuildResult*/> t{
|
||||
KeyedBuildResult{
|
||||
BuildResult{.inner{KeyedBuildResult::Failure{{
|
||||
.status = KeyedBuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
/* .path = */
|
||||
DerivedPath::Opaque{
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-xxx"},
|
||||
},
|
||||
},
|
||||
KeyedBuildResult{
|
||||
BuildResult{
|
||||
.inner{KeyedBuildResult::Failure{{
|
||||
.status = KeyedBuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
.isNonDeterministic = true,
|
||||
}}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
/* .path = */
|
||||
DerivedPath::Built{
|
||||
.drvPath = makeConstantStorePathRef(
|
||||
StorePath{
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
}),
|
||||
.outputs = OutputsSpec::Names{"out"},
|
||||
},
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
keyedBuildResult_1_29,
|
||||
"keyed-build-result-1.29",
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 29,
|
||||
}),
|
||||
({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<KeyedBuildResult, KeyedBuildResult /*, KeyedBuildResult*/> t{
|
||||
KeyedBuildResult{
|
||||
BuildResult{.inner{KeyedBuildResult::Failure{{
|
||||
.status = KeyedBuildResult::Failure::OutputRejected,
|
||||
.msg = HintFmt("no idea why"),
|
||||
}}}},
|
||||
/* .path = */
|
||||
DerivedPath::Opaque{
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-xxx"},
|
||||
},
|
||||
},
|
||||
KeyedBuildResult{
|
||||
BuildResult{
|
||||
.inner{KeyedBuildResult::Failure{{
|
||||
.status = KeyedBuildResult::Failure::NotDeterministic,
|
||||
.msg = HintFmt("no idea why"),
|
||||
.isNonDeterministic = true,
|
||||
}}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
/* .path = */
|
||||
DerivedPath::Built{
|
||||
.drvPath = makeConstantStorePathRef(
|
||||
StorePath{
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
}),
|
||||
.outputs = OutputsSpec::Names{"out"},
|
||||
},
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
unkeyedValidPathInfo_1_15,
|
||||
"unkeyed-valid-path-info-1.15",
|
||||
1 << 8 | 15,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 15,
|
||||
}),
|
||||
(std::tuple<UnkeyedValidPathInfo, UnkeyedValidPathInfo>{
|
||||
({
|
||||
UnkeyedValidPathInfo info{
|
||||
@@ -456,7 +505,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
validPathInfo_1_15,
|
||||
"valid-path-info-1.15",
|
||||
1 << 8 | 15,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 15,
|
||||
}),
|
||||
(std::tuple<ValidPathInfo, ValidPathInfo>{
|
||||
({
|
||||
ValidPathInfo info{
|
||||
@@ -505,7 +557,10 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
validPathInfo_1_16,
|
||||
"valid-path-info-1.16",
|
||||
1 << 8 | 16,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 16,
|
||||
}),
|
||||
(std::tuple<ValidPathInfo, ValidPathInfo, ValidPathInfo>{
|
||||
({
|
||||
ValidPathInfo info{
|
||||
@@ -660,7 +715,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_30,
|
||||
"client-handshake-info_1_30",
|
||||
1 << 8 | 30,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 30,
|
||||
}),
|
||||
(std::tuple<WorkerProto::ClientHandshakeInfo>{
|
||||
{},
|
||||
}))
|
||||
@@ -669,7 +727,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_33,
|
||||
"client-handshake-info_1_33",
|
||||
1 << 8 | 33,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 33,
|
||||
}),
|
||||
(std::tuple<WorkerProto::ClientHandshakeInfo, WorkerProto::ClientHandshakeInfo>{
|
||||
{
|
||||
.daemonNixVersion = std::optional{"foo"},
|
||||
@@ -683,7 +744,10 @@ VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_35,
|
||||
"client-handshake-info_1_35",
|
||||
1 << 8 | 35,
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 35,
|
||||
}),
|
||||
(std::tuple<WorkerProto::ClientHandshakeInfo, WorkerProto::ClientHandshakeInfo>{
|
||||
{
|
||||
.daemonNixVersion = std::optional{"foo"},
|
||||
@@ -736,17 +800,36 @@ TEST_F(WorkerProtoTest, handshake_features)
|
||||
auto clientThread = std::thread([&]() {
|
||||
FdSink out{toServer.writeSide.get()};
|
||||
FdSource in{toClient.readSide.get()};
|
||||
clientResult = WorkerProto::BasicClientConnection::handshake(out, in, 123, {"bar", "aap", "mies", "xyzzy"});
|
||||
clientResult = WorkerProto::BasicClientConnection::handshake(
|
||||
out,
|
||||
in,
|
||||
WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 123,
|
||||
},
|
||||
{"bar", "aap", "mies", "xyzzy"});
|
||||
});
|
||||
|
||||
FdSink out{toClient.writeSide.get()};
|
||||
FdSource in{toServer.readSide.get()};
|
||||
auto daemonResult = WorkerProto::BasicServerConnection::handshake(out, in, 456, {"foo", "bar", "xyzzy"});
|
||||
auto daemonResult = WorkerProto::BasicServerConnection::handshake(
|
||||
out,
|
||||
in,
|
||||
WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 200,
|
||||
},
|
||||
{"foo", "bar", "xyzzy"});
|
||||
|
||||
clientThread.join();
|
||||
|
||||
EXPECT_EQ(clientResult, daemonResult);
|
||||
EXPECT_EQ(std::get<0>(clientResult), 123u);
|
||||
EXPECT_EQ(
|
||||
std::get<0>(clientResult),
|
||||
(WorkerProto::Version{
|
||||
.major = 1,
|
||||
.minor = 123,
|
||||
}));
|
||||
EXPECT_EQ(std::get<1>(clientResult), WorkerProto::FeatureSet({"bar", "xyzzy"}));
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ struct TunnelLogger : public Logger
|
||||
if (!ex)
|
||||
to << STDERR_LAST;
|
||||
else {
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 26) {
|
||||
if (clientVersion >= WorkerProto::Version{1, 26}) {
|
||||
to << STDERR_ERROR << *ex;
|
||||
} else {
|
||||
to << STDERR_ERROR << ex->what() << ex->info().status;
|
||||
@@ -149,7 +149,7 @@ struct TunnelLogger : public Logger
|
||||
const Fields & fields,
|
||||
ActivityId parent) override
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20) {
|
||||
if (clientVersion < WorkerProto::Version{1, 20}) {
|
||||
if (!s.empty())
|
||||
log(lvl, s + "...");
|
||||
return;
|
||||
@@ -162,7 +162,7 @@ struct TunnelLogger : public Logger
|
||||
|
||||
void stopActivity(ActivityId act) override
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20)
|
||||
if (clientVersion < WorkerProto::Version{1, 20})
|
||||
return;
|
||||
StringSink buf;
|
||||
buf << STDERR_STOP_ACTIVITY << act;
|
||||
@@ -171,7 +171,7 @@ struct TunnelLogger : public Logger
|
||||
|
||||
void result(ActivityId act, ResultType type, const Fields & fields) override
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20)
|
||||
if (clientVersion < WorkerProto::Version{1, 20})
|
||||
return;
|
||||
StringSink buf;
|
||||
buf << STDERR_RESULT << act << type << fields;
|
||||
@@ -325,7 +325,7 @@ static void performOp(
|
||||
auto paths = WorkerProto::Serialise<StorePathSet>::read(*store, rconn);
|
||||
|
||||
SubstituteFlag substitute = NoSubstitute;
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 27) {
|
||||
if (conn.protoVersion >= WorkerProto::Version{1, 27}) {
|
||||
substitute = readInt(conn.from) ? Substitute : NoSubstitute;
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ static void performOp(
|
||||
}
|
||||
|
||||
case WorkerProto::Op::AddToStore: {
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 25) {
|
||||
if (conn.protoVersion >= WorkerProto::Version{1, 25}) {
|
||||
auto name = readString(conn.from);
|
||||
auto camStr = readString(conn.from);
|
||||
auto refs = WorkerProto::Serialise<StorePathSet>::read(*store, rconn);
|
||||
@@ -798,7 +798,7 @@ static void performOp(
|
||||
case WorkerProto::Op::QuerySubstitutablePathInfos: {
|
||||
SubstitutablePathInfos infos;
|
||||
StorePathCAMap pathsMap = {};
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) < 22) {
|
||||
if (conn.protoVersion < WorkerProto::Version{1, 22}) {
|
||||
auto paths = WorkerProto::Serialise<StorePathSet>::read(*store, rconn);
|
||||
for (auto & path : paths)
|
||||
pathsMap.emplace(path, std::nullopt);
|
||||
@@ -897,7 +897,7 @@ static void performOp(
|
||||
if (!trusted)
|
||||
info.ultimate = false;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 23) {
|
||||
if (conn.protoVersion >= WorkerProto::Version{1, 23}) {
|
||||
logger->startWork();
|
||||
{
|
||||
FramedSource source(conn.from);
|
||||
@@ -909,7 +909,7 @@ static void performOp(
|
||||
else {
|
||||
std::unique_ptr<Source> source;
|
||||
StringSink saved;
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 21)
|
||||
if (conn.protoVersion >= WorkerProto::Version{1, 21})
|
||||
source = std::make_unique<TunnelSource>(conn.from, conn.to);
|
||||
else {
|
||||
TeeSource tee{conn.from, saved};
|
||||
@@ -943,7 +943,7 @@ static void performOp(
|
||||
|
||||
case WorkerProto::Op::RegisterDrvOutput: {
|
||||
logger->startWork();
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) < 31) {
|
||||
if (conn.protoVersion < WorkerProto::Version{1, 31}) {
|
||||
auto outputId = WorkerProto::Serialise<DrvOutput>::read(*store, rconn);
|
||||
auto outputPath = StorePath(readString(conn.from));
|
||||
store->registerDrvOutput(Realisation{{.outPath = outputPath}, outputId});
|
||||
@@ -960,7 +960,7 @@ static void performOp(
|
||||
auto outputId = WorkerProto::Serialise<DrvOutput>::read(*store, rconn);
|
||||
auto info = store->queryRealisation(outputId);
|
||||
logger->stopWork();
|
||||
if (GET_PROTOCOL_MINOR(conn.protoVersion) < 31) {
|
||||
if (conn.protoVersion < WorkerProto::Version{1, 31}) {
|
||||
std::set<StorePath> outPaths;
|
||||
if (info)
|
||||
outPaths.insert(info->outPath);
|
||||
@@ -1016,9 +1016,9 @@ void processConnection(ref<Store> store, FdSource && from, FdSink && to, Trusted
|
||||
|
||||
/* Exchange the greeting. */
|
||||
auto [protoVersion, features] =
|
||||
WorkerProto::BasicServerConnection::handshake(to, from, PROTOCOL_VERSION, WorkerProto::allFeatures);
|
||||
WorkerProto::BasicServerConnection::handshake(to, from, WorkerProto::latest, WorkerProto::allFeatures);
|
||||
|
||||
if (protoVersion < MINIMUM_PROTOCOL_VERSION)
|
||||
if (protoVersion < WorkerProto::minimum)
|
||||
throw Error("the Nix client version is too old");
|
||||
|
||||
WorkerProto::BasicServerConnection conn;
|
||||
|
||||
@@ -8,10 +8,6 @@ namespace nix {
|
||||
#define SERVE_MAGIC_1 0x390c9deb
|
||||
#define SERVE_MAGIC_2 0x5452eecb
|
||||
|
||||
#define SERVE_PROTOCOL_VERSION (2 << 8 | 7)
|
||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||
|
||||
struct StoreDirConfig;
|
||||
struct Source;
|
||||
|
||||
@@ -37,7 +33,38 @@ struct ServeProto
|
||||
*
|
||||
* @todo Convert to struct with separate major vs minor fields.
|
||||
*/
|
||||
using Version = unsigned int;
|
||||
struct Version
|
||||
{
|
||||
unsigned int major;
|
||||
uint8_t minor;
|
||||
|
||||
constexpr auto operator<=>(const Version &) const = default;
|
||||
|
||||
/**
|
||||
* Convert to wire format for protocol compatibility.
|
||||
* Format: (major << 8) | minor
|
||||
*/
|
||||
constexpr unsigned int toWire() const
|
||||
{
|
||||
return (major << 8) | minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from wire format.
|
||||
*/
|
||||
static constexpr Version fromWire(unsigned int wire)
|
||||
{
|
||||
return {
|
||||
.major = (wire & 0xff00) >> 8,
|
||||
.minor = static_cast<uint8_t>(wire & 0x00ff),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr Version latest = {
|
||||
.major = 2,
|
||||
.minor = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* A unidirectional read connection, to be used by the read half of the
|
||||
|
||||
@@ -10,13 +10,6 @@ namespace nix {
|
||||
#define WORKER_MAGIC_1 0x6e697863
|
||||
#define WORKER_MAGIC_2 0x6478696f
|
||||
|
||||
/* Note: you generally shouldn't change the protocol version. Define a
|
||||
new `WorkerProto::Feature` instead. */
|
||||
#define PROTOCOL_VERSION (1 << 8 | 38)
|
||||
#define MINIMUM_PROTOCOL_VERSION (1 << 8 | 18)
|
||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||
|
||||
#define STDERR_NEXT 0x6f6c6d67
|
||||
#define STDERR_READ 0x64617461 // data needed from source
|
||||
#define STDERR_WRITE 0x64617416 // data for sink
|
||||
@@ -57,7 +50,46 @@ struct WorkerProto
|
||||
*
|
||||
* @todo Convert to struct with separate major vs minor fields.
|
||||
*/
|
||||
using Version = unsigned int;
|
||||
struct Version
|
||||
{
|
||||
unsigned int major;
|
||||
uint8_t minor;
|
||||
|
||||
constexpr auto operator<=>(const Version &) const = default;
|
||||
|
||||
/**
|
||||
* Convert to wire format for protocol compatibility.
|
||||
* Format: (major << 8) | minor
|
||||
*/
|
||||
constexpr unsigned int toWire() const
|
||||
{
|
||||
return (major << 8) | minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from wire format.
|
||||
*/
|
||||
static constexpr Version fromWire(unsigned int wire)
|
||||
{
|
||||
return {
|
||||
.major = (wire & 0xff00) >> 8,
|
||||
.minor = static_cast<uint8_t>(wire & 0x00ff),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @note you generally shouldn't change the protocol version. Define a new
|
||||
* `WorkerProto::Feature` instead.
|
||||
*/
|
||||
static constexpr Version latest = {
|
||||
.major = 1,
|
||||
.minor = 38,
|
||||
};
|
||||
static constexpr Version minimum = {
|
||||
.major = 1,
|
||||
.minor = 18,
|
||||
};
|
||||
|
||||
/**
|
||||
* A unidirectional read connection, to be used by the read half of the
|
||||
|
||||
@@ -73,7 +73,7 @@ ref<LegacySSHStore::Connection> LegacySSHStore::openConnection()
|
||||
TeeSource tee(conn->from, saved);
|
||||
try {
|
||||
conn->remoteVersion =
|
||||
ServeProto::BasicClientConnection::handshake(conn->to, tee, SERVE_PROTOCOL_VERSION, config->authority.host);
|
||||
ServeProto::BasicClientConnection::handshake(conn->to, tee, ServeProto::latest, config->authority.host);
|
||||
} catch (SerialisationError & e) {
|
||||
// in.close(): Don't let the remote block on us not writing.
|
||||
conn->sshConn->in.close();
|
||||
@@ -290,7 +290,7 @@ void LegacySSHStore::connect()
|
||||
unsigned int LegacySSHStore::getProtocol()
|
||||
{
|
||||
auto conn(connections->get());
|
||||
return conn->remoteVersion;
|
||||
return conn->remoteVersion.toWire();
|
||||
}
|
||||
|
||||
pid_t LegacySSHStore::getConnectionPid()
|
||||
|
||||
@@ -1494,7 +1494,7 @@ void LocalStore::verifyPath(
|
||||
|
||||
unsigned int LocalStore::getProtocol()
|
||||
{
|
||||
return PROTOCOL_VERSION;
|
||||
return WorkerProto::latest.toWire();
|
||||
}
|
||||
|
||||
std::optional<TrustedFlag> LocalStore::isTrustedClient()
|
||||
|
||||
@@ -83,9 +83,9 @@ void RemoteStore::initConnection(Connection & conn)
|
||||
StringSink saved;
|
||||
TeeSource tee(conn.from, saved);
|
||||
try {
|
||||
auto [protoVersion, features] =
|
||||
WorkerProto::BasicClientConnection::handshake(conn.to, tee, PROTOCOL_VERSION, WorkerProto::allFeatures);
|
||||
if (protoVersion < MINIMUM_PROTOCOL_VERSION)
|
||||
auto [protoVersion, features] = WorkerProto::BasicClientConnection::handshake(
|
||||
conn.to, tee, WorkerProto::latest, WorkerProto::allFeatures);
|
||||
if (protoVersion < WorkerProto::minimum)
|
||||
throw Error("the Nix daemon version is too old");
|
||||
conn.protoVersion = protoVersion;
|
||||
conn.features = features;
|
||||
@@ -208,7 +208,7 @@ void RemoteStore::querySubstitutablePathInfos(const StorePathCAMap & pathsMap, S
|
||||
auto conn(getConnection());
|
||||
|
||||
conn->to << WorkerProto::Op::QuerySubstitutablePathInfos;
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) < 22) {
|
||||
if (conn->protoVersion < WorkerProto::Version{1, 22}) {
|
||||
StorePathSet paths;
|
||||
for (auto & path : pathsMap)
|
||||
paths.insert(path.first);
|
||||
@@ -264,7 +264,7 @@ StorePathSet RemoteStore::queryValidDerivers(const StorePath & path)
|
||||
|
||||
StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) {
|
||||
if (WorkerProto::Version::fromWire(getProtocol()) >= WorkerProto::Version{1, 22}) {
|
||||
return Store::queryDerivationOutputs(path);
|
||||
}
|
||||
auto conn(getConnection());
|
||||
@@ -277,7 +277,7 @@ StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
||||
std::map<std::string, std::optional<StorePath>>
|
||||
RemoteStore::queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore_)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) {
|
||||
if (WorkerProto::Version::fromWire(getProtocol()) >= WorkerProto::Version{1, 22}) {
|
||||
if (!evalStore_) {
|
||||
auto conn(getConnection());
|
||||
conn->to << WorkerProto::Op::QueryDerivationOutputMap;
|
||||
@@ -328,7 +328,7 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
|
||||
std::optional<ConnectionHandle> conn_(getConnection());
|
||||
auto & conn = *conn_;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 25) {
|
||||
if (conn->protoVersion >= WorkerProto::Version{1, 25}) {
|
||||
|
||||
conn->to << WorkerProto::Op::AddToStore << name << caMethod.renderWithAlgo(hashAlgo);
|
||||
WorkerProto::write(*this, *conn, references);
|
||||
@@ -447,9 +447,9 @@ void RemoteStore::addToStore(const ValidPathInfo & info, Source & source, Repair
|
||||
WorkerProto::write(*this, *conn, info.sigs);
|
||||
conn->to << renderContentAddress(info.ca) << repair << !checkSigs;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 23) {
|
||||
if (conn->protoVersion >= WorkerProto::Version{1, 23}) {
|
||||
conn.withFramedSink([&](Sink & sink) { copyNAR(source, sink); });
|
||||
} else if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 21) {
|
||||
} else if (conn->protoVersion >= WorkerProto::Version{1, 21}) {
|
||||
conn.processStderr(0, &source);
|
||||
} else {
|
||||
copyNAR(source, conn->to);
|
||||
@@ -493,7 +493,7 @@ void RemoteStore::addMultipleToStore(
|
||||
|
||||
void RemoteStore::addMultipleToStore(Source & source, RepairFlag repair, CheckSigsFlag checkSigs)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(getConnection()->protoVersion) >= 32) {
|
||||
if (getConnection()->protoVersion >= WorkerProto::Version{1, 32}) {
|
||||
auto conn(getConnection());
|
||||
conn->to << WorkerProto::Op::AddMultipleToStore << repair << !checkSigs;
|
||||
conn.withFramedSink([&](Sink & sink) { source.drainInto(sink); });
|
||||
@@ -505,7 +505,7 @@ void RemoteStore::registerDrvOutput(const Realisation & info)
|
||||
{
|
||||
auto conn(getConnection());
|
||||
conn->to << WorkerProto::Op::RegisterDrvOutput;
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) < 31) {
|
||||
if (conn->protoVersion < WorkerProto::Version{1, 31}) {
|
||||
WorkerProto::write(*this, *conn, info.id);
|
||||
conn->to << std::string(info.outPath.to_string());
|
||||
} else {
|
||||
@@ -520,7 +520,7 @@ void RemoteStore::queryRealisationUncached(
|
||||
try {
|
||||
auto conn(getConnection());
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) < 27) {
|
||||
if (conn->protoVersion < WorkerProto::Version{1, 27}) {
|
||||
warn("the daemon is too old to support content-addressing derivations, please upgrade it to 2.4");
|
||||
return callback(nullptr);
|
||||
}
|
||||
@@ -530,7 +530,7 @@ void RemoteStore::queryRealisationUncached(
|
||||
conn.processStderr();
|
||||
|
||||
auto real = [&]() -> std::shared_ptr<const UnkeyedRealisation> {
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) < 31) {
|
||||
if (conn->protoVersion < WorkerProto::Version{1, 31}) {
|
||||
auto outPaths = WorkerProto::Serialise<std::set<StorePath>>::read(*this, *conn);
|
||||
if (outPaths.empty())
|
||||
return nullptr;
|
||||
@@ -590,7 +590,7 @@ std::vector<KeyedBuildResult> RemoteStore::buildPathsWithResults(
|
||||
std::optional<ConnectionHandle> conn_(getConnection());
|
||||
auto & conn = *conn_;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 34) {
|
||||
if (conn->protoVersion >= WorkerProto::Version{1, 34}) {
|
||||
conn->to << WorkerProto::Op::BuildPathsWithResults;
|
||||
WorkerProto::write(*this, *conn, paths);
|
||||
conn->to << buildMode;
|
||||
@@ -754,7 +754,7 @@ MissingPaths RemoteStore::queryMissing(const std::vector<DerivedPath> & targets)
|
||||
{
|
||||
{
|
||||
auto conn(getConnection());
|
||||
if (GET_PROTOCOL_MINOR(conn->protoVersion) < 19)
|
||||
if (conn->protoVersion < WorkerProto::Version{1, 19})
|
||||
// Don't hold the connection handle in the fallback case
|
||||
// to prevent a deadlock.
|
||||
goto fallback;
|
||||
@@ -796,7 +796,7 @@ void RemoteStore::connect()
|
||||
unsigned int RemoteStore::getProtocol()
|
||||
{
|
||||
auto conn(connections->get());
|
||||
return conn->protoVersion;
|
||||
return conn->protoVersion.toWire();
|
||||
}
|
||||
|
||||
std::optional<TrustedFlag> RemoteStore::isTrustedClient()
|
||||
|
||||
@@ -8,14 +8,14 @@ namespace nix {
|
||||
ServeProto::Version ServeProto::BasicClientConnection::handshake(
|
||||
BufferedSink & to, Source & from, ServeProto::Version localVersion, std::string_view host)
|
||||
{
|
||||
to << SERVE_MAGIC_1 << localVersion;
|
||||
to << SERVE_MAGIC_1 << localVersion.toWire();
|
||||
to.flush();
|
||||
|
||||
unsigned int magic = readInt(from);
|
||||
if (magic != SERVE_MAGIC_2)
|
||||
throw Error("'nix-store --serve' protocol mismatch from '%s'", host);
|
||||
auto remoteVersion = readInt(from);
|
||||
if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200 || GET_PROTOCOL_MINOR(remoteVersion) < 5)
|
||||
auto remoteVersion = ServeProto::Version::fromWire(readInt(from));
|
||||
if (remoteVersion.major != 2 || remoteVersion < ServeProto::Version{2, 5})
|
||||
throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);
|
||||
return std::min(remoteVersion, localVersion);
|
||||
}
|
||||
@@ -26,9 +26,9 @@ ServeProto::BasicServerConnection::handshake(BufferedSink & to, Source & from, S
|
||||
unsigned int magic = readInt(from);
|
||||
if (magic != SERVE_MAGIC_1)
|
||||
throw Error("protocol mismatch");
|
||||
to << SERVE_MAGIC_2 << localVersion;
|
||||
to << SERVE_MAGIC_2 << localVersion.toWire();
|
||||
to.flush();
|
||||
auto remoteVersion = readInt(from);
|
||||
auto remoteVersion = ServeProto::Version::fromWire(readInt(from));
|
||||
return std::min(remoteVersion, localVersion);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ BuildResult ServeProto::Serialise<BuildResult>::read(const StoreDirConfig & stor
|
||||
auto status = ServeProto::Serialise<BuildResultStatus>::read(store, {conn.from});
|
||||
conn.from >> errorMsg;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 3)
|
||||
if (conn.version >= ServeProto::Version{2, 3})
|
||||
conn.from >> res.timesBuilt >> isNonDeterministic >> res.startTime >> res.stopTime;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 6) {
|
||||
if (conn.version >= ServeProto::Version{2, 6}) {
|
||||
auto builtOutputs = ServeProto::Serialise<DrvOutputs>::read(store, conn);
|
||||
for (auto && [output, realisation] : builtOutputs)
|
||||
success.builtOutputs.insert_or_assign(std::move(output.outputName), std::move(realisation));
|
||||
@@ -63,9 +63,9 @@ void ServeProto::Serialise<BuildResult>::write(
|
||||
default value for the fields that don't exist in that case. */
|
||||
auto common = [&](std::string_view errorMsg, bool isNonDeterministic, const auto & builtOutputs) {
|
||||
conn.to << errorMsg;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 3)
|
||||
if (conn.version >= ServeProto::Version{2, 3})
|
||||
conn.to << res.timesBuilt << isNonDeterministic << res.startTime << res.stopTime;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 6) {
|
||||
if (conn.version >= ServeProto::Version{2, 6}) {
|
||||
DrvOutputs builtOutputsFullKey;
|
||||
for (auto & [output, realisation] : builtOutputs)
|
||||
builtOutputsFullKey.insert_or_assign(realisation.id, realisation);
|
||||
@@ -100,7 +100,7 @@ UnkeyedValidPathInfo ServeProto::Serialise<UnkeyedValidPathInfo>::read(const Sto
|
||||
readLongLong(conn.from); // download size, unused
|
||||
info.narSize = readLongLong(conn.from);
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 4) {
|
||||
if (conn.version >= ServeProto::Version{2, 4}) {
|
||||
auto s = readString(conn.from);
|
||||
if (!s.empty())
|
||||
info.narHash = Hash::parseAnyPrefixed(s);
|
||||
@@ -120,7 +120,7 @@ void ServeProto::Serialise<UnkeyedValidPathInfo>::write(
|
||||
// !!! Maybe we want compression?
|
||||
conn.to << info.narSize // downloadSize, lie a little
|
||||
<< info.narSize;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 4) {
|
||||
if (conn.version >= ServeProto::Version{2, 4}) {
|
||||
conn.to << info.narHash.to_string(HashFormat::Nix32, true) << renderContentAddress(info.ca);
|
||||
ServeProto::write(store, conn, info.sigs);
|
||||
}
|
||||
@@ -132,13 +132,13 @@ ServeProto::Serialise<ServeProto::BuildOptions>::read(const StoreDirConfig & sto
|
||||
BuildOptions options;
|
||||
options.maxSilentTime = readInt(conn.from);
|
||||
options.buildTimeout = readInt(conn.from);
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 2)
|
||||
if (conn.version >= ServeProto::Version{2, 2})
|
||||
options.maxLogSize = readNum<unsigned long>(conn.from);
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 3) {
|
||||
if (conn.version >= ServeProto::Version{2, 3}) {
|
||||
options.nrRepeats = readInt(conn.from);
|
||||
options.enforceDeterminism = readInt(conn.from);
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 7) {
|
||||
if (conn.version >= ServeProto::Version{2, 7}) {
|
||||
options.keepFailed = (bool) readInt(conn.from);
|
||||
}
|
||||
return options;
|
||||
@@ -148,12 +148,12 @@ void ServeProto::Serialise<ServeProto::BuildOptions>::write(
|
||||
const StoreDirConfig & store, WriteConn conn, const ServeProto::BuildOptions & options)
|
||||
{
|
||||
conn.to << options.maxSilentTime << options.buildTimeout;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 2)
|
||||
if (conn.version >= ServeProto::Version{2, 2})
|
||||
conn.to << options.maxLogSize;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 3)
|
||||
if (conn.version >= ServeProto::Version{2, 3})
|
||||
conn.to << options.nrRepeats << options.enforceDeterminism;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 7) {
|
||||
if (conn.version >= ServeProto::Version{2, 7}) {
|
||||
conn.to << ((int) options.keepFailed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ WorkerProto::BasicClientConnection::processStderrReturn(Sink * sink, Source * so
|
||||
}
|
||||
|
||||
else if (msg == STDERR_ERROR) {
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 26) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 26}) {
|
||||
ex = std::make_exception_ptr(readError(from));
|
||||
} else {
|
||||
auto error = readString(from);
|
||||
@@ -122,7 +122,7 @@ WorkerProto::BasicClientConnection::processStderrReturn(Sink * sink, Source * so
|
||||
// explain to users what's going on when their daemon is
|
||||
// older than #4628 (2023).
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::DynamicDerivations)
|
||||
&& GET_PROTOCOL_MINOR(protoVersion) <= 35) {
|
||||
&& protoVersion <= WorkerProto::Version{1, 35}) {
|
||||
auto m = e.msg();
|
||||
if (m.find("parsing derivation") != std::string::npos && m.find("expected string") != std::string::npos
|
||||
&& m.find("Derive([") != std::string::npos)
|
||||
@@ -161,24 +161,24 @@ std::tuple<WorkerProto::Version, WorkerProto::FeatureSet> WorkerProto::BasicClie
|
||||
WorkerProto::Version localVersion,
|
||||
const WorkerProto::FeatureSet & supportedFeatures)
|
||||
{
|
||||
to << WORKER_MAGIC_1 << localVersion;
|
||||
to << WORKER_MAGIC_1 << localVersion.toWire();
|
||||
to.flush();
|
||||
|
||||
unsigned int magic = readInt(from);
|
||||
if (magic != WORKER_MAGIC_2)
|
||||
throw Error("nix-daemon protocol mismatch from");
|
||||
auto daemonVersion = readInt(from);
|
||||
auto daemonVersion = WorkerProto::Version::fromWire(readInt(from));
|
||||
|
||||
if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
|
||||
if (daemonVersion.major != WorkerProto::latest.major)
|
||||
throw Error("Nix daemon protocol version not supported");
|
||||
if (GET_PROTOCOL_MINOR(daemonVersion) < 10)
|
||||
if (daemonVersion < WorkerProto::Version{1, 10})
|
||||
throw Error("the Nix daemon version is too old");
|
||||
|
||||
auto protoVersion = std::min(daemonVersion, localVersion);
|
||||
|
||||
/* Exchange features. */
|
||||
WorkerProto::FeatureSet daemonFeatures;
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 38) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 38}) {
|
||||
to << supportedFeatures;
|
||||
to.flush();
|
||||
daemonFeatures = readStrings<WorkerProto::FeatureSet>(from);
|
||||
@@ -196,15 +196,15 @@ std::tuple<WorkerProto::Version, WorkerProto::FeatureSet> WorkerProto::BasicServ
|
||||
unsigned int magic = readInt(from);
|
||||
if (magic != WORKER_MAGIC_1)
|
||||
throw Error("protocol mismatch");
|
||||
to << WORKER_MAGIC_2 << localVersion;
|
||||
to << WORKER_MAGIC_2 << localVersion.toWire();
|
||||
to.flush();
|
||||
auto clientVersion = readInt(from);
|
||||
auto clientVersion = WorkerProto::Version::fromWire(readInt(from));
|
||||
|
||||
auto protoVersion = std::min(clientVersion, localVersion);
|
||||
|
||||
/* Exchange features. */
|
||||
WorkerProto::FeatureSet clientFeatures;
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 38) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 38}) {
|
||||
clientFeatures = readStrings<WorkerProto::FeatureSet>(from);
|
||||
to << supportedFeatures;
|
||||
to.flush();
|
||||
@@ -217,15 +217,15 @@ WorkerProto::ClientHandshakeInfo WorkerProto::BasicClientConnection::postHandsha
|
||||
{
|
||||
WorkerProto::ClientHandshakeInfo res;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 14) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 14}) {
|
||||
// Obsolete CPU affinity.
|
||||
to << 0;
|
||||
}
|
||||
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 11)
|
||||
if (protoVersion >= WorkerProto::Version{1, 11})
|
||||
to << false; // obsolete reserveSpace
|
||||
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 33)
|
||||
if (protoVersion >= WorkerProto::Version{1, 33})
|
||||
to.flush();
|
||||
|
||||
return WorkerProto::Serialise<ClientHandshakeInfo>::read(store, *this);
|
||||
@@ -233,12 +233,12 @@ WorkerProto::ClientHandshakeInfo WorkerProto::BasicClientConnection::postHandsha
|
||||
|
||||
void WorkerProto::BasicServerConnection::postHandshake(const StoreDirConfig & store, const ClientHandshakeInfo & info)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 14 && readInt(from)) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 14} && readInt(from)) {
|
||||
// Obsolete CPU affinity.
|
||||
readInt(from);
|
||||
}
|
||||
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 11)
|
||||
if (protoVersion >= WorkerProto::Version{1, 11})
|
||||
readInt(from); // obsolete reserveSpace
|
||||
|
||||
WorkerProto::write(store, *this, info);
|
||||
@@ -256,7 +256,7 @@ std::optional<UnkeyedValidPathInfo> WorkerProto::BasicClientConnection::queryPat
|
||||
return std::nullopt;
|
||||
throw;
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 17) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 17}) {
|
||||
bool valid;
|
||||
from >> valid;
|
||||
if (!valid)
|
||||
@@ -268,10 +268,10 @@ std::optional<UnkeyedValidPathInfo> WorkerProto::BasicClientConnection::queryPat
|
||||
StorePathSet WorkerProto::BasicClientConnection::queryValidPaths(
|
||||
const StoreDirConfig & store, bool * daemonException, const StorePathSet & paths, SubstituteFlag maybeSubstitute)
|
||||
{
|
||||
assert(GET_PROTOCOL_MINOR(protoVersion) >= 12);
|
||||
assert((protoVersion >= WorkerProto::Version{1, 12}));
|
||||
to << WorkerProto::Op::QueryValidPaths;
|
||||
WorkerProto::write(store, *this, paths);
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 27) {
|
||||
if (protoVersion >= WorkerProto::Version{1, 27}) {
|
||||
to << maybeSubstitute;
|
||||
}
|
||||
processStderr(daemonException);
|
||||
|
||||
@@ -153,7 +153,7 @@ void WorkerProto::Serialise<std::optional<std::chrono::microseconds>>::write(
|
||||
DerivedPath WorkerProto::Serialise<DerivedPath>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
auto s = readString(conn.from);
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
||||
if (conn.version >= WorkerProto::Version{1, 30}) {
|
||||
return DerivedPath::parseLegacy(store, s);
|
||||
} else {
|
||||
return parsePathWithOutputs(store, s).toDerivedPath();
|
||||
@@ -163,7 +163,7 @@ DerivedPath WorkerProto::Serialise<DerivedPath>::read(const StoreDirConfig & sto
|
||||
void WorkerProto::Serialise<DerivedPath>::write(
|
||||
const StoreDirConfig & store, WorkerProto::WriteConn conn, const DerivedPath & req)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
||||
if (conn.version >= WorkerProto::Version{1, 30}) {
|
||||
conn.to << req.to_string_legacy(store);
|
||||
} else {
|
||||
auto sOrDrvPath = StorePathWithOutputs::tryFromDerivedPath(req);
|
||||
@@ -174,8 +174,8 @@ void WorkerProto::Serialise<DerivedPath>::write(
|
||||
throw Error(
|
||||
"trying to request '%s', but daemon protocol %d.%d is too old (< 1.29) to request a derivation file",
|
||||
store.printStorePath(drvPath),
|
||||
GET_PROTOCOL_MAJOR(conn.version),
|
||||
GET_PROTOCOL_MINOR(conn.version));
|
||||
conn.version.major,
|
||||
conn.version.minor);
|
||||
},
|
||||
[&](std::monostate) {
|
||||
throw Error(
|
||||
@@ -216,14 +216,14 @@ BuildResult WorkerProto::Serialise<BuildResult>::read(const StoreDirConfig & sto
|
||||
auto status = WorkerProto::Serialise<BuildResultStatus>::read(store, {conn.from});
|
||||
conn.from >> errorMsg;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 29) {
|
||||
if (conn.version >= WorkerProto::Version{1, 29}) {
|
||||
conn.from >> res.timesBuilt >> isNonDeterministic >> res.startTime >> res.stopTime;
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 37) {
|
||||
if (conn.version >= WorkerProto::Version{1, 37}) {
|
||||
res.cpuUser = WorkerProto::Serialise<std::optional<std::chrono::microseconds>>::read(store, conn);
|
||||
res.cpuSystem = WorkerProto::Serialise<std::optional<std::chrono::microseconds>>::read(store, conn);
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 28) {
|
||||
if (conn.version >= WorkerProto::Version{1, 28}) {
|
||||
auto builtOutputs = WorkerProto::Serialise<DrvOutputs>::read(store, conn);
|
||||
for (auto && [output, realisation] : builtOutputs)
|
||||
success.builtOutputs.insert_or_assign(std::move(output.outputName), std::move(realisation));
|
||||
@@ -258,14 +258,14 @@ void WorkerProto::Serialise<BuildResult>::write(
|
||||
default value for the fields that don't exist in that case. */
|
||||
auto common = [&](std::string_view errorMsg, bool isNonDeterministic, const auto & builtOutputs) {
|
||||
conn.to << errorMsg;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 29) {
|
||||
if (conn.version >= WorkerProto::Version{1, 29}) {
|
||||
conn.to << res.timesBuilt << isNonDeterministic << res.startTime << res.stopTime;
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 37) {
|
||||
if (conn.version >= WorkerProto::Version{1, 37}) {
|
||||
WorkerProto::write(store, conn, res.cpuUser);
|
||||
WorkerProto::write(store, conn, res.cpuSystem);
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 28) {
|
||||
if (conn.version >= WorkerProto::Version{1, 28}) {
|
||||
DrvOutputs builtOutputsFullKey;
|
||||
for (auto & [output, realisation] : builtOutputs)
|
||||
builtOutputsFullKey.insert_or_assign(realisation.id, realisation);
|
||||
@@ -310,7 +310,7 @@ UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const St
|
||||
info.deriver = std::move(deriver);
|
||||
info.references = WorkerProto::Serialise<StorePathSet>::read(store, conn);
|
||||
conn.from >> info.registrationTime >> info.narSize;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 16) {
|
||||
if (conn.version >= WorkerProto::Version{1, 16}) {
|
||||
conn.from >> info.ultimate;
|
||||
info.sigs = WorkerProto::Serialise<std::set<Signature>>::read(store, conn);
|
||||
info.ca = ContentAddress::parseOpt(readString(conn.from));
|
||||
@@ -325,7 +325,7 @@ void WorkerProto::Serialise<UnkeyedValidPathInfo>::write(
|
||||
conn.to << pathInfo.narHash.to_string(HashFormat::Base16, false);
|
||||
WorkerProto::write(store, conn, pathInfo.references);
|
||||
conn.to << pathInfo.registrationTime << pathInfo.narSize;
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 16) {
|
||||
if (conn.version >= WorkerProto::Version{1, 16}) {
|
||||
conn.to << pathInfo.ultimate;
|
||||
WorkerProto::write(store, conn, pathInfo.sigs);
|
||||
conn.to << renderContentAddress(pathInfo.ca);
|
||||
@@ -337,11 +337,11 @@ WorkerProto::Serialise<WorkerProto::ClientHandshakeInfo>::read(const StoreDirCon
|
||||
{
|
||||
WorkerProto::ClientHandshakeInfo res;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 33) {
|
||||
if (conn.version >= WorkerProto::Version{1, 33}) {
|
||||
res.daemonNixVersion = readString(conn.from);
|
||||
}
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 35) {
|
||||
if (conn.version >= WorkerProto::Version{1, 35}) {
|
||||
res.remoteTrustsUs = WorkerProto::Serialise<std::optional<TrustedFlag>>::read(store, conn);
|
||||
} else {
|
||||
// We don't know the answer; protocol to old.
|
||||
@@ -354,12 +354,12 @@ WorkerProto::Serialise<WorkerProto::ClientHandshakeInfo>::read(const StoreDirCon
|
||||
void WorkerProto::Serialise<WorkerProto::ClientHandshakeInfo>::write(
|
||||
const StoreDirConfig & store, WriteConn conn, const WorkerProto::ClientHandshakeInfo & info)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 33) {
|
||||
if (conn.version >= WorkerProto::Version{1, 33}) {
|
||||
assert(info.daemonNixVersion);
|
||||
conn.to << *info.daemonNixVersion;
|
||||
}
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 35) {
|
||||
if (conn.version >= WorkerProto::Version{1, 35}) {
|
||||
WorkerProto::write(store, conn, info.remoteTrustsUs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,8 @@ namespace {
|
||||
std::string formatProtocol(unsigned int proto)
|
||||
{
|
||||
if (proto) {
|
||||
auto major = GET_PROTOCOL_MAJOR(proto) >> 8;
|
||||
auto minor = GET_PROTOCOL_MINOR(proto);
|
||||
return fmt("%1%.%2%", major, minor);
|
||||
auto version = WorkerProto::Version::fromWire(proto);
|
||||
return fmt("%1%.%2%", version.major, version.minor);
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
@@ -153,9 +152,9 @@ struct CmdConfigCheck : StoreCommand
|
||||
|
||||
bool checkStoreProtocol(unsigned int storeProto)
|
||||
{
|
||||
unsigned int clientProto = GET_PROTOCOL_MAJOR(SERVE_PROTOCOL_VERSION) == GET_PROTOCOL_MAJOR(storeProto)
|
||||
? SERVE_PROTOCOL_VERSION
|
||||
: PROTOCOL_VERSION;
|
||||
auto storeVersion = WorkerProto::Version::fromWire(storeProto);
|
||||
unsigned int clientProto = (storeVersion.major == ServeProto::latest.major) ? ServeProto::latest.toWire()
|
||||
: WorkerProto::latest.toWire();
|
||||
|
||||
if (clientProto != storeProto) {
|
||||
std::ostringstream ss;
|
||||
|
||||
@@ -882,7 +882,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||
FdSink out(getStandardOutput());
|
||||
|
||||
/* Exchange the greeting. */
|
||||
ServeProto::Version clientVersion = ServeProto::BasicServerConnection::handshake(out, in, SERVE_PROTOCOL_VERSION);
|
||||
ServeProto::Version clientVersion = ServeProto::BasicServerConnection::handshake(out, in, ServeProto::latest);
|
||||
|
||||
ServeProto::ReadConn rconn{
|
||||
.from = in,
|
||||
@@ -909,9 +909,9 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||
// these conditions.
|
||||
settings.maxSilentTime = options.maxSilentTime;
|
||||
settings.buildTimeout = options.buildTimeout;
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 2)
|
||||
if (clientVersion >= ServeProto::Version{2, 2})
|
||||
settings.maxLogSize = options.maxLogSize;
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 3) {
|
||||
if (clientVersion >= ServeProto::Version{2, 3}) {
|
||||
if (options.nrRepeats != 0) {
|
||||
throw Error("client requested repeating builds, but this is not currently implemented");
|
||||
}
|
||||
@@ -924,7 +924,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||
// client asked for.
|
||||
settings.getLocalSettings().runDiffHook = true;
|
||||
}
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 7) {
|
||||
if (clientVersion >= ServeProto::Version{2, 7}) {
|
||||
settings.keepFailed = options.keepFailed;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user