This repository was archived by the owner on Jul 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMetal.java
More file actions
234 lines (183 loc) · 9.19 KB
/
Copy pathMetal.java
File metadata and controls
234 lines (183 loc) · 9.19 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package profile;
import java.net.InetAddress;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import core.data.InterfaceData;
import core.exec.PasswordExec;
import core.iface.IUnit;
import core.model.InterfaceModel;
import core.model.NetworkModel;
import core.model.ServerModel;
import core.profile.AStructuredProfile;
import core.unit.SimpleUnit;
import core.unit.fs.DirUnit;
import core.unit.fs.FileChecksumUnit;
import core.unit.fs.FileDownloadUnit;
import core.unit.pkg.InstalledUnit;
public class Metal extends AStructuredProfile {
private Virtualisation hypervisor;
private HypervisorScripts backups;
private Vector<ServerModel> services;
private ServerModel me;
public Metal(ServerModel me, NetworkModel networkModel) {
super("metal", me, networkModel);
this.me = me;
this.hypervisor = new Virtualisation(me, networkModel);
this.backups = new HypervisorScripts(me, networkModel);
this.services = new Vector<ServerModel>();
}
public Vector<ServerModel> getServices() {
return services;
}
protected Vector<IUnit> getInstalled() {
Vector<IUnit> units = new Vector<IUnit>();
units.addAll(hypervisor.getInstalled());
units.addAll(backups.getInstalled());
units.addElement(new DirUnit("media_dir", "proceed", networkModel.getData().getHypervisorThornsecBase(me.getLabel())));
units.addElement(new InstalledUnit("whois", "proceed", "whois"));
units.addElement(new InstalledUnit("tmux", "proceed", "tmux"));
units.addElement(new InstalledUnit("socat", "proceed", "socat"));
return units;
}
protected Vector<IUnit> getPersistentConfig() {
Vector<IUnit> units = new Vector<IUnit>();
String fuse = "";
fuse += "#user_allow_other";
units.addElement(((ServerModel)me).getConfigsModel().addConfigFile("fuse", "proceed", fuse, "/etc/fuse.conf"));
units.addAll(backups.getPersistentConfig());
return units;
}
public Vector<IUnit> getNetworking() {
Vector<IUnit> units = new Vector<IUnit>();
InterfaceModel im = me.getInterfaceModel();
me.setFirstOctet(10);
me.setSecondOctet(networkModel.getMetalServers().indexOf(me) + 1);
me.setThirdOctet(0);
int i = 0;
//Add this machine's interfaces
for (Map.Entry<String, String> lanIface : networkModel.getData().getLanIfaces(me.getLabel()).entrySet() ) {
if (me.isRouter() || networkModel.getData().getWanIfaces(me.getLabel()).containsKey(lanIface.getKey())) { //Try not to duplicate ifaces if we're a Router/Metal
continue;
}
InetAddress subnet = networkModel.stringToIP(me.getFirstOctet() + "." + me.getSecondOctet() + "." + me.getThirdOctet() + "." + (i * 4));
InetAddress router = networkModel.stringToIP(me.getFirstOctet() + "." + me.getSecondOctet() + "." + me.getThirdOctet() + "." + ((i * 4) + 1));
InetAddress address = networkModel.stringToIP(me.getFirstOctet() + "." + me.getSecondOctet() + "." + me.getThirdOctet() + "." + ((i * 4) + 2));
InetAddress broadcast = networkModel.stringToIP(me.getFirstOctet() + "." + me.getSecondOctet() + "." + me.getThirdOctet() + "." + ((i * 4) + 3));
InetAddress netmask = networkModel.getData().getNetmask();
im.addIface(new InterfaceData(me.getLabel(),
lanIface.getKey(),
lanIface.getValue(),
"static",
null,
subnet,
address,
netmask,
broadcast,
router,
"comment goes here")
);
}
me.addRequiredEgress("gensho.ftp.acc.umu.se");
me.addRequiredEgress("github.com");
return units;
}
protected Vector<IUnit> getLiveConfig() {
Vector<IUnit> units = new Vector<IUnit>();
Vector<String> urls = new Vector<String>();
for (ServerModel service : me.getServices()) {
String newURL = networkModel.getData().getDebianIsoUrl(service.getLabel());
if (urls.contains(newURL)) {
continue;
}
else {
urls.add(newURL);
}
}
for (String url : urls) {
String filename = null;
String cleanedFilename = null;
try {
filename = Paths.get(new URI(url).getPath()).getFileName().toString();
cleanedFilename = filename.replaceAll("[^A-Za-z0-9]", "_");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "It doesn't appear that " + url + " is a valid link to a Debian ISO.\n\nPlease fix this in your JSON");
System.exit(1);
}
units.addElement(new FileDownloadUnit("debian_netinst_iso_" + cleanedFilename, "metal_genisoimage_installed",
url,
networkModel.getData().getHypervisorThornsecBase(me.getLabel()) + "/" + filename,
"The Debian net install ISO couldn't be downloaded. Please check the URI in your config."));
units.addElement(new FileChecksumUnit("debian_netinst_iso", "debian_netinst_iso_" + cleanedFilename + "_downloaded",
networkModel.getData().getHypervisorThornsecBase(me.getLabel()) + "/" + filename,
networkModel.getData().getDebianIsoSha512(me.getLabel()),
"The sha512 sum of the Debian net install in your config doesn't match what has been downloaded. This could mean your connection is man-in-the-middle'd, or it could just be that the file has been updated on the server. "
+ "Please check http://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS (64 bit) or http://cdimage.debian.org/debian-cd/current/i386/iso-cd/SHA512SUMS (32 bit) for the correct checksum."));
}
for (ServerModel service : me.getServices()) {
String password = "";
String serviceLabel = service.getLabel();
Boolean expirePasswords = false;
PasswordExec pass = new PasswordExec(serviceLabel, networkModel);
if (pass.init()) {
password = pass.getPassword();
password = Pattern.quote(password); //Turn special characters into literal so they don't get parsed out
password = password.substring(2, password.length()-2).trim(); //Remove '\Q' and '\E' from beginning/end since we're not using this as a regex
password = password.replace("\"", "\\\""); //Also, make sure quote marks are properly escaped!
}
if (pass.isDefaultPassword()) {
expirePasswords = true;
}
units.addElement(new SimpleUnit(serviceLabel + "_password", "proceed",
serviceLabel.toUpperCase() + "_PASSWORD=`printf \"" + password + "\" | mkpasswd -s -m md5`",
"echo $" + serviceLabel.toUpperCase() + "_PASSWORD", "", "fail",
"Couldn't set the passphrase for " + serviceLabel + ". You won't be able to configure this service."));
String bridge = networkModel.getData().getMetalIface(serviceLabel);
if (bridge == null || bridge.equals("")) {
bridge = me.getNetworkData().getLanIfaces(me.getLabel()).getOrDefault(0, "vm" + service.getThirdOctet());
}
units.addAll(hypervisor.buildIso(service.getLabel(), hypervisor.preseed(service.getLabel(), expirePasswords)));
units.addAll(hypervisor.buildServiceVm(service.getLabel(), bridge));
String bootDiskDir = networkModel.getData().getHypervisorThornsecBase(me.getLabel()) + "/disks/boot/" + serviceLabel + "/";
String dataDiskDir = networkModel.getData().getHypervisorThornsecBase(me.getLabel()) + "/disks/data/" + serviceLabel + "/";
units.addElement(new SimpleUnit(serviceLabel + "_boot_disk_formatted", "proceed",
"",
"sudo bash -c 'export LIBGUESTFS_BACKEND_SETTINGS=force_tcg;"
+ "virt-filesystems -a " + bootDiskDir + serviceLabel + "_boot.v*'", "", "fail",
"Boot disk is unformatted (therefore has no OS on it), please configure the service and try mounting again."));
//For now, do this as root. We probably want to move to another user, idk
units.addElement(new SimpleUnit(serviceLabel + "_boot_disk_loopback_mounted", serviceLabel + "_boot_disk_formatted",
"sudo bash -c '"
+ " export LIBGUESTFS_BACKEND_SETTINGS=force_tcg;"
+ " guestmount -a " + bootDiskDir + serviceLabel + "_boot.v*"
+ " -i" //Inspect the disk for the relevant partition
+ " -o direct_io" //All read operations must be done against live, not cache
+ " --ro" //_MOUNT THE DISK READ ONLY_
+ " " + bootDiskDir + "live/"
+"'",
"sudo mount | grep " + bootDiskDir, "", "fail",
"I was unable to loopback mount the boot disk for " + serviceLabel + " in " + getLabel() + "."));
units.addElement(new SimpleUnit(serviceLabel + "_data_disk_formatted", "proceed",
"",
"sudo bash -c 'export LIBGUESTFS_BACKEND_SETTINGS=force_tcg;"
+ "virt-filesystems -a " + dataDiskDir + serviceLabel + "_data.v*'", "", "fail",
"Data disk is unformatted (therefore hasn't been configured), please configure the service and try mounting again."));
units.addElement(new SimpleUnit(serviceLabel + "_data_disk_loopback_mounted", serviceLabel + "_data_disk_formatted",
"sudo bash -c '"
+ " export LIBGUESTFS_BACKEND_SETTINGS=force_tcg;"
+ " guestmount -a " + dataDiskDir + serviceLabel + "_data.v*"
+ " -m /dev/sda1" //Mount the first partition
+ " -o direct_io" //All read operations must be done against live, not cache
+ " --ro" //_MOUNT THE DISK READ ONLY_
+ " " + dataDiskDir + "live/"
+"'",
"sudo mount | grep " + dataDiskDir, "", "fail",
"I was unable to loopback mount the data disk for " + serviceLabel + " in " + getLabel() + ". Backups will not work."));
}
return units;
}
}