~ubuntu-virt/vmbuilder/trunk

« back to all changes in this revision

Viewing changes to VMBuilder/__init__.py

  • Committer: Soren Hansen
  • Date: 2008-06-27 12:47:26 UTC
  • Revision ID: soren.hansen@canonical.com-20080627124726-kj690sepircudc3h
Import python rewrite.. It's not quite at a useful point yet (only cli+kvm+hardy is in a usable state), but it's getting there..

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
import builder
 
3
import os
 
4
import logging
 
5
import optparse
 
6
import tempfile
 
7
 
 
8
import VMBuilder.plugins
 
9
from VMBuilder.util import run_cmd 
 
10
from VMBuilder.disk import Disk
 
11
from VMBuilder.hypervisor import Hypervisor
 
12
from VMBuilder.distro import Distro
 
13
from opts import create_optparser
 
14
from VMBuilder.plugins import load_plugins
 
15
from exception import VMBuilderException
 
16
   
 
17
def register_hypervisor(cls):
 
18
    hypervisors[cls.arg] = cls
 
19
 
 
20
def register_distro(cls):
 
21
    distros[cls.arg] = cls
 
22
 
 
23
# This is waaay to simple. All it does is to apply the sizes of root, swap and opt
 
24
# and put them all on a single disk (in separate partitions, of course)
 
25
def disk_layout():
 
26
    size = options.rootsize + options.swapsize + options.optsize
 
27
    disk = Disk(dir=workdir, size='%dM' % size)
 
28
    offset = 0
 
29
    disk.add_part(offset, options.rootsize, 'ext3', '/')
 
30
    offset += options.rootsize+1
 
31
    disk.add_part(offset, options.swapsize, 'swap', 'swap')
 
32
    offset += options.swapsize+1
 
33
    if options.optsize > 0:
 
34
        disk.add_part(offset, options.optsize, 'ext3', '/opt')
 
35
    return [disk]
 
36
 
 
37
def checkroot():
 
38
    if os.geteuid() != 0:
 
39
        optparser.error("This script must be run as root (e.g. via sudo)")
 
40
 
 
41
def parse_options():
 
42
    global options
 
43
    global optparser
 
44
    optparser.disable_interspersed_args()
 
45
    (options, args) = optparser.parse_args()
 
46
    if len(args) < 2:
 
47
        optparser.error("You need to specify at least the hypervisor type and the distro")
 
48
 
 
49
    if not args[0] in hypervisors.keys():
 
50
        optparser.error("Invalid hypervisor. Valid hypervisors: %s" % " ".join(hypervisors.keys()))
 
51
    else:
 
52
        hypervisor = hypervisors[args[0]]()
 
53
        if getattr(hypervisor, 'extend_optparse', None):
 
54
            optparser = hypervisor.extend_optparse(optparser)
 
55
 
 
56
    if not args[1] in distros.keys():
 
57
        optparser.error("Invalid distro. Valid distros: %s" % " ".join(distros.keys()))
 
58
    else:
 
59
        distro = distros[args[1]]()
 
60
        if getattr(distro, 'extend_optparse', None):
 
61
            optparser = distro.extend_optparse(optparser)
 
62
 
 
63
    optparser.set_defaults(destdir='%s-%s' % (args[0], args[1]))
 
64
    optparser.enable_interspersed_args()
 
65
    (options, args) = optparser.parse_args()
 
66
    return (distro, hypervisor)
 
67
 
 
68
def run():
 
69
    checkroot()     
 
70
 
 
71
    finished = False
 
72
    try:
 
73
        logging.debug('Loading plugins')
 
74
        load_plugins()
 
75
        (distro, hypervisor) = parse_options()
 
76
        create_directory_structure()
 
77
 
 
78
        distro.set_defaults()
 
79
 
 
80
        create_partitions()
 
81
        mount_partitions()
 
82
 
 
83
        install(distro, hypervisor)
 
84
        
 
85
        umount_partitions()
 
86
 
 
87
        hypervisor.convert()
 
88
 
 
89
        finished = True
 
90
    except VMBuilderException,e:
 
91
        raise e
 
92
    finally:
 
93
        if not finished:
 
94
            logging.critical("Oh, dear, an exception occurred")
 
95
        cleanup()
 
96
 
 
97
def cleanup():
 
98
    logging.info("Cleaning up the mess...")
 
99
    while len(cleanup_cb) > 0:
 
100
        cleanup_cb.pop(0)()
 
101
 
 
102
def add_clean_cb(cb):
 
103
    cleanup_cb.insert(0, cb)
 
104
 
 
105
def add_clean_cmd(*argv, **kwargs):
 
106
    add_clean_cb(lambda : run_cmd(*argv, **kwargs))
 
107
 
 
108
def create_partitions():
 
109
    for disk in VMBuilder.disks:
 
110
        disk.create()
 
111
 
 
112
def get_ordered_partitions():
 
113
    parts = []
 
114
    for disk in VMBuilder.disks:
 
115
        parts += disk.partitions
 
116
    parts.sort(lambda x,y: len(x.mntpnt)-len(y.mntpnt))
 
117
    return parts
 
118
 
 
119
def mount_partitions():
 
120
    logging.info('Mounting target filesystem')
 
121
    parts = get_ordered_partitions()
 
122
    for part in parts:
 
123
        if part.type != part.TYPE_SWAP: 
 
124
            logging.debug('Mounting %s', part.mntpnt) 
 
125
            part.mntpath = '%s%s' % (rootmnt, part.mntpnt)
 
126
            if not os.path.exists(part.mntpath):
 
127
                os.makedirs(part.mntpath)
 
128
            run_cmd('mount', part.mapdev, part.mntpath)
 
129
            add_clean_cmd('umount', part.mntpath, ignore_fail=True)
 
130
 
 
131
def umount_partitions():
 
132
    logging.info('Unmounting target filesystem')
 
133
    parts = get_ordered_partitions()
 
134
    parts.reverse()
 
135
    for part in parts:
 
136
        if part.type != part.TYPE_SWAP: 
 
137
            logging.debug('Unounting %s', part.mntpath) 
 
138
            run_cmd('umount', part.mntpath)
 
139
    for disk in disks:
 
140
        disk.unmap()
 
141
 
 
142
def install(distro, hypervisor):
 
143
    if options.in_place:
 
144
        destdir = rootmnt
 
145
    else:
 
146
        destdir = tmproot
 
147
 
 
148
    logging.info("Installing guest operating system. This might take some time...")
 
149
    distro.install(destdir=destdir)
 
150
 
 
151
    logging.info("Copying to disk images")
 
152
    run_cmd('rsync', '-aHA', '%s/' % tmproot, rootmnt)
 
153
 
 
154
    logging.info("Installing bootloader")
 
155
    distro.install_bootloader()
 
156
 
 
157
def convert():
 
158
    for disk in VMBuilder.disks:
 
159
        disk.convert('/home/soren/disk1.qcow2', 'qcow2')
 
160
 
 
161
def bootpart():
 
162
    return disks[0].partitions[0]
 
163
 
 
164
cleanup_cb = []
 
165
optparser = create_optparser()
 
166
distros = {}
 
167
hypervisors = {}