-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.py
More file actions
320 lines (304 loc) · 13.8 KB
/
Copy pathinstall.py
File metadata and controls
320 lines (304 loc) · 13.8 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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#!/usr/bin/env python
import os,sys,urllib2,platform,re
# check if root with geteuid
if os.geteuid() != 0:
print "Please re-run this script with root privileges, i.e. 'sudo ./install.py'\n"
sys.exit()
# check if running on Mac
mac = (platform.system() == 'Darwin')
# check if all necessary system utilities are present
if mac:
exitcode = os.system("which clear diskutil grep gunzip dd")
else:
exitcode = os.system("which clear fdisk grep umount mount cut gunzip dd blockdev")
if exitcode != 0:
print "Error: your operating system does not include all the necessary utilities to continue."
if mac:
print "Utilities necessery: clear diskutil grep gunzip dd"
else:
print "Utilities necessery: clear fdisk grep umount mount cut gunzip dd blockdev"
print "Please install them."
sys.exit()
os.system("clear")
print "Raspbmc installer for Linux and OS X"
print "http://raspbmc.com"
print "----------------------------------------"
# yes/no prompt adapted from http://code.activestate.com/recipes/577058-query-yesno/
def query_yes_no(question, default="yes"):
valid = {"yes":"yes", "y":"yes", "ye":"yes", "no":"no", "n":"no"}
if default == None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while 1:
print question + prompt
choice = raw_input().lower()
if default is not None and choice == '':
return default
elif choice in valid.keys():
return valid[choice]
else:
print "Please respond with 'yes' or 'no' (or 'y' or 'n').\n"
def chunk_report(bytes_so_far, chunk_size, total_size):
percent = float(bytes_so_far) / total_size
percent = round(percent*100, 2)
sys.stdout.write("Downloaded %0.2f of %0.2f MiB (%0.2f%%)\r" %
(float(bytes_so_far)/1048576, float(total_size)/1048576, percent))
if bytes_so_far >= total_size:
sys.stdout.write('\n')
def chunk_read(response, file, chunk_size, report_hook):
total_size = response.info().getheader('Content-Length').strip()
total_size = int(total_size)
bytes_so_far = 0
while 1:
chunk = response.read(chunk_size)
file.write(chunk)
bytes_so_far += len(chunk)
if not chunk:
break
if report_hook:
report_hook(bytes_so_far, chunk_size, total_size)
return bytes_so_far
def download(url):
print "Downloading, please be patient..."
dl = urllib2.urlopen(url)
dlFile = open('installer.img.gz', 'w')
chunk_read(dl, dlFile, 8192, chunk_report)
#dlFile.write(dl.read())
dlFile.close()
def deviceinput():
# they must know the risks!
verified = "no"
raw_input("Please ensure you've inserted your SD card, and press Enter to continue.")
while verified is not "yes":
print ""
if mac:
print "Enter the 'IDENTIFIER' of the device you would like imaged:"
else:
print "Enter the 'Disk' you would like imaged, from the following list:"
listdevices()
print ""
if mac:
device = raw_input("Enter your choice here (e.g. 'disk1', 'disk2'): ")
else:
device = raw_input("Enter your choice here (e.g. 'mmcblk0' or 'sdd'): ")
# Add /dev/ to device if not entered
if not device.startswith("/dev/"):
device = "/dev/" + device
if os.path.exists(device) == True:
print "It is your own responsibility to ensure there is no data loss! Please backup your system before imaging"
print "You should also ensure you agree with the Raspbmc License Agreeement"
cont = query_yes_no("Are you sure you want to install Raspbmc to '\033[31m" + device + "\033[0m' and accept the license agreement?", "no")
if cont == "no":
sys.exit()
else:
verified = "yes"
else:
print "Device doesn't exist"
# and thus we are not 'verified'
verified = "no"
return device
def listdevices():
if mac:
print " #: TYPE NAME SIZE IDENTIFIER"
os.system('diskutil list | grep "0:"')
else:
os.system('fdisk -l | grep -E "Disk /dev/"')
def unmount(drive): # unmounts drive
print "Unmounting all partitions..."
if mac:
exitcode = os.system("diskutil unmountDisk " + drive)
else:
# check if partitions are mounted; if so, unmount
if os.system("mount | grep " + drive + " > /dev/null") == 0:
exitcode = os.system("umount `mount | grep " + drive + " | cut -f1 -d ' '`")
else:
# partitions were not mounted; must pass error check
exitcode = 0
if exitcode != 0:
print 'Error: the drive couldn\'t be unmounted, exiting...'
sys.exit()
def mount(drive): # mounts drive to mount_raspbmc/
print "Mounting the drive for post-installation settings"
if mac:
os.system("diskutil mount -mountPoint mount_raspbmc/ " + drive + "s1")
else:
if os.path.exists(drive + "p1"):
drive = drive + "p"
os.system("mount " + drive + "1 mount_raspbmc/")
def imagedevice(drive, imagefile):
print ""
unmount(drive)
# use the system's built in imaging and extraction facilities
print "Please wait while Raspbmc is installed to your SD card..."
print "This may take some time and no progress will be reported until it has finished."
if mac:
os.system("gunzip -c " + imagefile + " | dd of=" + drive + " bs=1m")
else:
os.system("gunzip -c " + imagefile + " | dd of=" + drive + " bs=1M")
# Linux kernel must reload the partition table
os.system("blockdev --rereadpt " + drive)
print "Installation complete."
# Post-install settings
def settings(drive):
if mac:
unmount(drive)
if os.path.exists("mount_raspbmc"):
os.rmdir("mount_raspbmc")
os.mkdir("mount_raspbmc")
mount(drive)
if os.path.exists("mount_raspbmc/start_x.elf"):
# prompt for USB/NFS setup
usbnfs = query_yes_no("Would you like to install Raspbmc to a USB stick or an NFS share?\nNote that this still requires an SD card for booting.", "no")
if usbnfs == "yes":
print "Please choose the install type:"
print "1. USB install"
print "2. NFS install"
installchoice = raw_input()
while installchoice != "1" and installchoice != "2":
print "Please specify a valid option"
installchoice = raw_input()
if installchoice == "1":
usb = open("mount_raspbmc/usb", "w")
usb.close()
elif installchoice == "2":
nfsip = raw_input("NFS server IP Adress (e.g. '192.168.1.100'): ")
nfspath = raw_input("NFS share path (e.g. '/path/to/nfs/share'): ")
nfs = open("mount_raspbmc/nfs", "w")
nfs.write(nfsip + ":" + nfspath + "\n")
nfs.close()
# prompt for network setup
inet = query_yes_no("Would you like to configure networking manually? This is useful if you are configuring WiFi or a non-DHCP network", "no")
if inet == "yes":
print "Please choose the network type you would like to configure:"
print "1. Wired networking, non-DHCP"
print "2. Wireless networking"
inetchoice = raw_input()
while inetchoice != "1" and inetchoice != "2":
print "Please specify a valid option"
inetchoice = raw_input()
if inetchoice == "1":
mode = "0"
dhcp = "false"
ip = raw_input("IP Address (e.g. '192.168.101'): ")
subnet = raw_input("Subnet Mask (e.g. '255.255.255.0'): ")
dns = raw_input("DNS Server (e.g. '192.168.1.1'): ")
gateway = raw_input("Default Gateway (e.g. '192.168.1.1'): ")
# generic settings
wifidhcp = "true"
wifiip = "192.168.1.101"
wifisubnet = "255.255.255.0"
wifidns = "192.168.1.1"
wifigateway = "192.168.1.1"
ssid = "raspbmc"
keytype = "1"
key = "password"
adhoc = "false"
enable5g = "false"
elif inetchoice == "2":
mode = "1"
wifidhcp = query_yes_no("Use DHCP?", "yes")
if wifidhcp == "no":
wifidhcp = "false"
wifiip = raw_input("IP Address (e.g. '192.168.101'): ")
wifisubnet = raw_input("Subnet Mask (e.g. '255.255.255.0'): ")
wifidns = raw_input("DNS Server (e.g. '192.168.1.1'): ")
wifigateway = raw_input("Default Gateway (e.g. '192.168.1.1'): ")
else:
wifidhcp = "true"
# generic settings
wifiip = "192.168.1.101"
wifisubnet = "255.255.255.0"
wifidns = "192.168.1.1"
wifigateway = "192.168.1.1"
# generic ethernet settings
dhcp = "true"
ip = "192.168.1.101"
subnet = "255.255.255.0"
dns = "192.168.1.1"
gateway = "192.168.1.1"
# custom options
adhoc_yn = query_yes_no("Enable ad-hoc networking?", "no")
if adhoc_yn == "yes":
adhoc = "true"
else:
adhoc = "false"
enable5g_yn = query_yes_no("Enable 5Ghz only?", "no")
if enable5g_yn == "yes":
enable5g = "true"
else:
enable5g = "false"
ssid = raw_input("Please enter SSID (e.g. 'raspbmc_wifi'): ")
print "Please enter encryption type"
print "0. No encryption"
print "1. WEP Open Key"
print "2. WEP Shared Key"
print "3. WEP Dynamic Key"
print "4. WPA/WPA2"
keytype = raw_input()
if keytype != "0":
key = raw_input("Please enter encryption key (e.g. 'password'): ")
else:
key = "password"
settings = open("mount_raspbmc/settings.xml", "w")
settings.write("<settings>\n")
# ethernet settings
settings.write(" <setting id=\"nm.mode\" value=\"" + mode + "\" />\n")
settings.write(" <setting id=\"nm.dhcp\" value=\"" + dhcp + "\" />\n")
settings.write(" <setting id=\"nm.address\" value=\"" + ip + "\" />\n")
settings.write(" <setting id=\"nm.netmask\" value=\"" + subnet + "\" />\n")
settings.write(" <setting id=\"nm.dns\" value=\"" + dns + "\" />\n")
settings.write(" <setting id=\"nm.gateway\" value=\"" + gateway + "\" />\n")
settings.write(" <setting id=\"nm.force_update\" value=\"false\" />\n")
settings.write(" <setting id=\"nm.uid.enable\" value=\"true\" />\n")
settings.write(" <setting id=\"nm.search\" value=\"local\" />\n")
# wifi settings
settings.write(" <setting id=\"nm.wifi.dhcp\" value=\"" + wifidhcp + "\" />\n")
settings.write(" <setting id=\"nm.wifi.address\" value=\"" + wifiip + "\" />\n")
settings.write(" <setting id=\"nm.wifi.netmask\" value=\"" + wifisubnet + "\" />\n")
settings.write(" <setting id=\"nm.wifi.dns\" value=\"" + wifidns + "\" />\n")
settings.write(" <setting id=\"nm.wifi.gateway\" value=\"" + wifigateway + "\" />\n")
settings.write(" <setting id=\"nm.wifi.ssid\" value=\"" + ssid + "\" />\n")
settings.write(" <setting id=\"nm.wifi.security\" value=\"" + keytype + "\" />\n")
settings.write(" <setting id=\"nm.wifi.key\" value=\"" + key + "\" />\n")
settings.write(" <setting id=\"nm.wifi.adhoc\" value=\"" + adhoc + "\" />\n")
settings.write(" <setting id=\"nm.wifi.5GOnly\" value=\"" + enable5g + "\" />\n")
settings.write(" <setting id=\"nm.wifi.search\" value=\"local\" />\n")
settings.write("</settings>")
settings.close()
unmount(drive)
else:
print "Additional configuration such as USB/NFS and networking \033[31mnot supported\033[0m as the installer could not mount a FAT32 filesystem"
if os.path.exists("mount_raspbmc"):
os.rmdir("mount_raspbmc")
def raspbmcinstaller():
# configure the device to image
disk = deviceinput()
# should downloading and extraction be done?
redl = "" # so that redl == "yes" doesn't throw an error
if os.path.exists("installer.img.gz"):
redl = query_yes_no("It appears that the Raspbmc installation image has already been downloaded. Would you like to re-download it?", "no")
if redl == "yes" or not os.path.exists("installer.img.gz"):
# call the dl
download("http://download.raspbmc.com/downloads/bin/ramdistribution/installer.img.gz")
# now we can image
if mac:
regex = re.compile('/dev/r?(disk[0-9]+?)')
try:
disk = re.sub('r?disk', 'rdisk', regex.search(disk).group(0))
except:
print "Malformed disk specification -> ", disk
sys.exit()
imagedevice(disk, "installer.img.gz")
# post-install options, if supported by os
postinstall = query_yes_no("Would you like to setup your post-installation settings [ADVANCED]?", "no")
if postinstall == "yes":
settings(disk)
print ""
print "Raspbmc is now ready to finish setup on your Pi, please insert the SD card with an active internet connection"
print ""
raspbmcinstaller()