PERFORCE change 125068 for review
Ivan Voras
ivoras at FreeBSD.org
Sat Aug 11 14:57:23 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125068
Change 125068 by ivoras at ivoras_finstall on 2007/08/11 21:57:20
- Integrated makeimage (ISO image creator), pybackend and the installer
- pybackend now starts by default from the live CD
- the liveCD "install" user now has a desktop icon pointing to the installer
- fixed minor bugs in all three components
Affected files ...
.. //depot/projects/soc2007/ivoras_finstall/installer/finstall.py#9 edit
.. //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/bundle-spec#4 edit
.. //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/installer.desktop#1 add
.. //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/prelogin#1 add
.. //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/prelogin.txt#1 add
.. //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/pybackend.sh#1 add
.. //depot/projects/soc2007/ivoras_finstall/makeimage/makeimage.py#10 edit
.. //depot/projects/soc2007/ivoras_finstall/pybackend/systoolengine.py#6 edit
Differences ...
==== //depot/projects/soc2007/ivoras_finstall/installer/finstall.py#9 (text+ko) ====
@@ -1,5 +1,28 @@
-import sys
-import time
+#!/usr/local/bin/python
+# Copyright (c) 2007. Ivan Voras <ivoras at freebsd.org>
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# finstall Installer
+
+import os,sys,time
import logging
from types import MethodType
from xmlrpclib import ServerProxy
@@ -13,7 +36,9 @@
# Configured tracks
Steps_Novice = [
{ "tile" : "intro" },
- { "tile" : "ndisks" }
+ { "tile" : "ndisks" },
+ { "tile" : "nparts" },
+ { "tile" : "nfilesys" }
]
@@ -27,6 +52,7 @@
self.step_current = 0
self.step_track = MainWin.Steps_Novice
self._load_tile_nr(self.step_current)
+ self.backtrack = []
def __getitem__(self, key):
@@ -65,6 +91,16 @@
self._load_tile(self.step_track[tile_nr]["tile"])
+ def _set_next_tile(self, tile):
+ found = False
+ for i, t in enumerate(self.step_track):
+ if t["tile"] == tile:
+ self.step_current = i-1 # Actually this is not a clean hack, but it'll do for now
+ found = True
+ if not found:
+ logging.error("_set_next_tile cannot set tile to %s. Bogosity ahead." % tile)
+
+
# Handlers for the main window elements (the window itself, Next/Previous
# buttons, etc.
def on_mainwin_delete_event(self, obj, data):
@@ -113,6 +149,7 @@
except:
logging.exception("Error executing on_next handler in %s" % self.step_track[self.step_current]["tile"])
return
+ self.backtrack.append(self.step_track[self.step_current]["tile"])
self.step_current += 1
if self.step_current >= len(self.step_track):
self.step_current = 0 # XXX: Fix by disabling next/previous
@@ -130,9 +167,19 @@
except:
logging.exception("Error executing on_previous in %s" % self.step_track[self.step_current]["tile"])
return
- self.step_current -= 1
- if self.step_current < 0:
- self.step_current = len(self.step_track)-1 # XXX: fix by disabling next/previous
+ if len(self.backtrack) == 0 and self.step_current != 0:
+ self._show_message("Nothing to go back to!", "Error", p_type=gtk.MESSAGE_ERROR)
+ return
+ if len(self.backtrack) == 0:
+ self.step_current = 0
+ else:
+ tile = self.backtrack.pop()
+ self.step_current = -1
+ for i, t in enumerate(self.step_track):
+ if t["tile"] == tile:
+ self.step_current = i
+ if self.step_current < 0:
+ self._show_message("Cannot find tile %s" % tile, "Error", p_type.gtk.MESSAGE_ERROR)
self._load_tile_nr(self.step_current)
@@ -149,11 +196,13 @@
def intro_on_next(self):
if self["radio_novice"].get_active():
+ logging.info("track=Novice")
pass # The default track is Novice
elif self["radio_standard"].get_active():
print "standard"
elif self["radio_expert"].get_active():
print "expert"
+ self.trackdata = {}
return True
@@ -161,7 +210,7 @@
def ndisks_on_load(self):
self._load_label(self["label2"], "ndisks.txt")
drives = self.server.GetDrives()
- if len(drives) < 0:
+ if len(drives) < 1:
self._show_message("No usable drives detected.\nThis is a fatal error and the Installer cannot continue.", "Error", p_type=gtk.MESSAGE_ERROR)
return
@@ -178,9 +227,46 @@
return True
- # Handlers for "win1"
- def win1_on_button1_clicked(self, obj):
- print "clicked"
+ def ndisks_on_next(self):
+ row, col = self["disktree"].get_cursor()
+ if row == None or type(row) != type((1,)):
+ self._show_message("You need to pick a drive onto which FreeBSD will be installed.", "User intervention required")
+ return False
+ model = self["disktree"].get_model()
+ drive = model.get_value(model.get_iter(row), 0)
+ logging.info("ndisks.drive=%s" % drive)
+ self.trackdata["drive"] = drive
+ parts = self.server.GetDrivePartitions(drive)
+ if len(parts) == 0:
+ # The drive is not partitioned, so mark it for default configuration
+ self.trackdata["parts"] = None
+ logging.info("Drive %s is not partitioned" % drive)
+ self._set_next_tile("nfilesys")
+ else:
+ self.trackdata["parts"] = parts
+ logging.info("Drive %s is partitioned" % drive)
+ self._set_next_tile("nparts")
+
+ return True
+
+
+ def nparts_on_load(self):
+ parts = self.trackdata["parts"]
+ list = gtk.ListStore(str, str, str, str)
+ part_list = parts.keys()
+ part_list.sort()
+ for part in part_list:
+ list.append([part, parts[part]["fs_type"], "%d MB" % parts[part]["mediasize"]])
+ self["parttree"].set_model(list)
+ self["parttree"].append_column(self._make_column("Partition", 0, True))
+ self["parttree"].append_column(self._make_column("File system", 1))
+ self["parttree"].append_column(self._make_column("Size", 2, True))
+ self["parttree"].append_column(self._make_column("Valid target?", 3, True))
+ self["parttree"].set_cursor(0)
+ return True
+
+
+os.chdir(os.path.split(sys.argv[0])[0]) # attempt to chdir into the directory where the script is located
logging.basicConfig(level=logging.DEBUG)
w = MainWin()
==== //depot/projects/soc2007/ivoras_finstall/makeimage/bundles/bundle-spec#4 (text+ko) ====
@@ -4,6 +4,7 @@
# kw : expand keywords in the (text) file
# x : set execute bit to destination file
# a : append to destination file
+# d : directory (copy recursively)
/boot/loader.conf=loader.conf;kw
/etc/rc.conf=rc.conf;kw
/etc/X11/xorg.conf=xorg.conf;kw
@@ -19,4 +20,8 @@
/install/.config/autostart/xfce4-tips-autostart.desktop=xfce4-tips-autostart.desktop
/install/.xinitrc=dot.xinitrc;kw
/install/.config/xfce4/mcs_settings/gtk.xml=gtk.xml
+/install/installer=../../installer;d
+/install/pybackend=../../pybackend;d
+/install/Desktop/installer.desktop=installer.desktop
/usr/local/etc/fonts/local.conf=font.local.conf;kw
+/usr/local/etc/rc.d/pybackend.sh=pybackend.sh;kw;x
==== //depot/projects/soc2007/ivoras_finstall/makeimage/makeimage.py#10 (text+ko) ====
@@ -22,7 +22,7 @@
# finstall LiveCD image creator
-import os, os.path, sys, stat
+import os, os.path, sys, stat, shutil
from time import strftime
from getopt import getopt, GetoptError
from util import nukedir, execute, printmsg, cmdout, readline, initutils, getpkgdeps, getpkgfullname
@@ -54,7 +54,9 @@
print " -b Do buildworld / buildkernel before proceeding"
print " -c Assume installworld / installkernel phase has been"
print " done in WORKDIR/livecd and proceed with configuration"
- print " and ISO image build"
+ print " and ISO image build. If specified only once, packages"
+ print " will get built and installed, if specified twice,"
+ print " packages will be skipped."
if exit:
sys.exit(1)
else:
@@ -66,6 +68,7 @@
KERNEL = "GENERIC"
DoBuild = False
DoMakeRoot = True # Create / install livecd tree
+DoMakePkgs = True
LABEL = "FreeBSD7" # ISO9660 Volume label
BUNDLEDIR = "bundles"
BUNDLEFILE = "bundle-spec"
@@ -95,7 +98,10 @@
elif o == "-b":
DoBuild = True
elif o == "-c":
- DoMakeRoot = False
+ if DoMakeRoot:
+ DoMakeRoot = False
+ else:
+ DoMakePkgs = False # if -c is specified twice, skip packages
elif o == "-i":
ISO = a
elif o == "-x":
@@ -142,6 +148,10 @@
if not os.path.exists("%s/%s" % (WORKDIR, ZIMAGE_IMGNAME)):
print "No %s" % ZIMAGE_IMGNAME
sys.exit(1)
+if os.path.exists("/dev/md60"):
+ if os.popen("/sbin/mount -p").read().find("/dev/md60") != -1:
+ execute("umount /dev/md60")
+ execute("mdconfig -d -u 60")
execute("mdconfig -a -t vnode -f %s -u 60" % ZIMAGE_IMGNAME)
if DoMakeRoot:
execute("newfs /dev/md60")
@@ -180,7 +190,7 @@
str_time = strftime("%H:%M")
str_date = strftime("%Y-%m-%d")
-if PKGLISTFILE != None:
+if PKGLISTFILE != None and DoMakePkgs:
# Install packages into the liveCD tree, using chroot
printmsg("Bundling packages")
master_pkglist = []
@@ -249,24 +259,33 @@
flags = []
dest_file, src_file = line.split("=", 1)
cflist.append(dest_file)
- file_contents = file("%s/%s" % (BUNDLEDIR, src_file), "r").read()
- if "kw" in flags:
- file_contents = file_contents.replace("$label$", LABEL)
- file_contents = file_contents.replace("$time$", str_time)
- file_contents = file_contents.replace("$date$", str_date)
- file_contents = file_contents.replace("$dest_file$", dest_file)
- file_contents = file_contents.replace("$src_file$", src_file)
- filename = "%s%s" % (DESTDIR, dest_file)
- if not os.path.exists(os.path.dirname(filename)):
- os.makedirs(os.path.dirname(filename))
- if "a" in flags:
- df = file(filename, "a")
- else:
- df = file(filename, "w")
- df.write(file_contents)
- df.close()
- if "x" in flags:
- os.chmod("%s%s" % (DESTDIR, dest_file), stat.S_IRUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
+ if not 'd' in flags: # regular file
+ file_contents = file("%s/%s" % (BUNDLEDIR, src_file), "r").read()
+ if "kw" in flags:
+ file_contents = file_contents.replace("$label$", LABEL)
+ file_contents = file_contents.replace("$time$", str_time)
+ file_contents = file_contents.replace("$date$", str_date)
+ file_contents = file_contents.replace("$dest_file$", dest_file)
+ file_contents = file_contents.replace("$src_file$", src_file)
+ filename = "%s%s" % (DESTDIR, dest_file)
+ if not os.path.exists(os.path.dirname(filename)):
+ os.makedirs(os.path.dirname(filename))
+ if "a" in flags:
+ df = file(filename, "a")
+ else:
+ df = file(filename, "w")
+ df.write(file_contents)
+ df.close()
+ if "x" in flags:
+ os.chmod("%s%s" % (DESTDIR, dest_file), stat.S_IRUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
+ else: # copy entire directory
+ src_dir_name = "%s/%s" % (BUNDLEDIR, src_file)
+ dst_dir_name = "%s%s" % (DESTDIR, dest_file)
+ if os.path.exists(dst_dir_name):
+ printmsg("Removing %s" % dst_dir_name)
+ shutil.rmtree(dst_dir_name)
+ printmsg("copytree %s -> %s" % (src_dir_name, dst_dir_name))
+ shutil.copytree(src_dir_name, dst_dir_name, True)
if len(cflist) != 0:
printmsg("LiveCD will contain config files: %s" % " ".join(cflist))
f.close()
==== //depot/projects/soc2007/ivoras_finstall/pybackend/systoolengine.py#6 (text+ko) ====
@@ -19,7 +19,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# SysToolD Engine
+# SysToolD Engine: implements SysToolD XML-RPC methods
import os, sys
import re
@@ -104,13 +104,15 @@
found hardware.
RETURN VALUE:
The return value is a dictionary with device names
- as keys and another dictionary as values.
- {
- "ad0" : {
- "name": "ACME MegaDrive"
- "mediasize": 300000 # (MB)
- }
- }"""
+ as keys and another dictionary as values, containing keys:
+ name, mediasize
+ For example:
+ {
+ "ad0" : {
+ "name": "ACME MegaDrive",
+ "mediasize": 300000 # (MB)
+ }
+ }"""
drive_list = freebsd.get_sysctl("kern.disks").split(" ")
dmesg = freebsd.get_dmesg()
drive_dict = {}
@@ -151,14 +153,25 @@
ARGUMENTS:
drive : The drive to inspect
RETURN VALUE:
- The return value is a list of dictionaries."""
+ The return value is a dictionary whose keys are partition names
+ and values are dictionaries containing keys:
+ name, mediasize, sectorsize, type
+ For example:
+ {
+ "ad0s1a" : {
+ "name" : "ad0s1a",
+ "mediasize" : 100000, # MB
+ "sectorsize" : 512,
+ "type" : "BSD"
+ }
+ }"""
parts = {}
used_parts = []
geomxml = freebsd.get_geom_xml()
num_msdos_parts = 1
# enumerate MSDOS partitions
for cls in geomxml["mesh"]["class"]:
- if cls["name"].data == "MBR":
+ if cls["name"].data == "MBR" and "geom" in cls:
for geom in tolist(cls["geom"]):
if geom["name"].data == drive:
for prov in tolist(geom["provider"]):
@@ -172,7 +185,7 @@
num_msdos_parts += 1
# process BSDlabels, both dedicated and inside MSDOS partitions
for cls in geomxml["mesh"]["class"]:
- if cls["name"].data == "BSD":
+ if cls["name"].data == "BSD" and "geom" in cls:
for geom in tolist(cls["geom"]):
if geom["name"].data == drive:
# "raw" BSD partitions directly on the drive
More information about the p4-projects
mailing list