1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#pragma once
///@file
#include "lix/libstore/build/local-derivation-goal.hh"
#include "lix/libstore/gc-store.hh"
#include "lix/libstore/local-store.hh"
#include "lix/libutil/processes.hh"
#include <unistd.h>
namespace nix {
/**
* Linux-specific implementation of LocalStore
*/
class LinuxLocalStore : public LocalStore
{
public:
LinuxLocalStore(LocalStoreConfig config) : Store(config), LocalStore(config) {}
LinuxLocalStore(const std::string scheme, std::string path, LocalStoreConfig config)
: LinuxLocalStore(config)
{
throw UnimplementedError("LinuxLocalStore");
}
private:
kj::Promise<Result<void>> findPlatformRoots(UncheckedRoots & unchecked) override;
};
/**
* Linux-specific implementation of LocalDerivationGoal
*/
class LinuxLocalDerivationGoal : public LocalDerivationGoal
{
public:
using LocalDerivationGoal::LocalDerivationGoal;
~LinuxLocalDerivationGoal();
// NOTE these are all C strings because macos doesn't have constexpr std::string
// constructors, and std::string_view is a pain to turn into std::strings again.
static constexpr const char * PASTA_NS_IFNAME = "eth0";
static constexpr const char * PASTA_HOST_IPV4 = "169.254.1.1";
static constexpr const char * PASTA_CHILD_IPV4 = "169.254.1.2";
static constexpr const char * PASTA_IPV4_NETMASK = "16";
// randomly chosen 6to4 prefix, mapping the same ipv4ll as above.
// even if this id is used on the daemon host there should not be
// any collisions since ipv4ll should never be addressed by ipv6.
static constexpr const char * PASTA_HOST_IPV6 = "64:ff9b:1:4b8e:472e:a5c8:a9fe:0101";
static constexpr const char * PASTA_CHILD_IPV6 = "64:ff9b:1:4b8e:472e:a5c8:a9fe:0102";
private:
/*
* Destroy the cgroup otherwise another build
* may grab the current UID which is used in the cgroup name
* and then mess with a cgroup we might be reading statistics from.
*/
void cleanupHookFinally() override;
Pid pastaPid;
/**
* Create a special accessor that can access paths that were built within the sandbox's
* chroot.
*/
std::optional<ref<FSAccessor>> getChrootDirAwareFSAccessor() override;
void fillBuilderConfig(build::Request::Builder request) override;
/**
* Create and populate chroot
*/
void prepareSandbox() override;
/**
* Start child process in new namespaces,
* create /etc/passwd and /etc/group based on discovered uid/gid
*/
Pid startChild(AutoCloseFD setupFD, AutoCloseFD logPTY) override;
/**
* Kill all processes by build user.
*/
void killSandbox(bool getStatus) override;
bool supportsUidRange() override
{
return true;
}
std::string rewriteResolvConf(std::string fromHost);
/**
* Whether to run the build in a private network namespace.
*/
bool privateNetwork() const
{
return derivationType.value().isSandboxed();
}
/**
* Whether to run pasta for network-endowed derivations. Running pasta
* currently requires actively waiting for its net-ns setup to finish.
*/
bool runPasta()
{
if (!_runPasta) {
// don't launch pasta unless we have a tun device. in a build sandbox we
// commonly do not, and trying to run pasta anyway naturally won't work.
_runPasta = !privateNetwork() && settings.pastaPath != "" && pathExists("/dev/net/tun");
}
return *_runPasta;
}
std::optional<bool> _runPasta;
};
}
|