174
179
# Get disk parameters
176
(path, voltuple, volinst, device, bus, readOnly, ignore, size,
181
(path, voltuple, volinst, device, bus, readOnly, shared, size,
178
183
(disk, None, None, virtinst.VirtualDisk.DEVICE_DISK, None, False,
184
False, size, sparse, None)
181
186
(path, voltuple, volinst,
182
device, bus, readOnly, ignore,
183
size, sparse) = parse_disk_option(guest, disk, size)
187
device, bus, readOnly, shared,
188
size, sparse, cache) = parse_disk_option(guest, disk, size)
184
189
if not sparse and volinst:
185
190
volinst.allocation = volinst.capacity
187
192
d = virtinst.VirtualDisk(path=path, size=size, sparse=sparse,
188
193
volInstall=volinst, volName=voltuple,
189
readOnly=readOnly, device=device, bus=bus,
194
readOnly=readOnly, shareable=shared,
195
device=device, bus=bus, conn=guest.conn,
191
197
# Default file backed PV guests to tap driver
192
198
if d.type == virtinst.VirtualDisk.TYPE_FILE \
193
199
and not(hvm) and virtinst.util.is_blktap_capable():
336
355
geng.add_option("", "--cpuset", type="string", dest="cpuset",
337
356
action="callback", callback=cli.check_before_store,
338
357
help=_("Set which physical CPUs Domain can use."))
339
parser.add_option_group(geng)
341
fulg = OptionGroup(parser, _("Full Virtualization specific options."))
342
fulg.add_option("", "--sound", action="store_true", dest="sound",
343
default=False, help=_("Use sound device emulation"))
344
fulg.add_option("", "--os-type", type="string", dest="os_type",
358
geng.add_option("", "--os-type", type="string", dest="distro_type",
345
359
action="callback", callback=cli.check_before_store,
346
360
help=_("The OS type for fully virtualized guests, e.g. "
347
361
"'linux', 'unix', 'windows'"))
348
fulg.add_option("", "--os-variant", type="string", dest="os_variant",
362
geng.add_option("", "--os-variant", type="string", dest="distro_variant",
349
363
action="callback", callback=cli.check_before_store,
350
364
help=_("The OS variant for fully virtualized guests, "
351
365
"e.g. 'fedora6', 'rhel5', 'solaris10', 'win2k'"))
366
geng.add_option("", "--host-device", type="string", dest="hostdevs",
367
action="callback", callback=cli.check_before_append,
368
help=_("Physical host device to attach to the domain."))
369
parser.add_option_group(geng)
371
fulg = OptionGroup(parser, _("Full Virtualization specific options"))
372
fulg.add_option("", "--sound", action="store_true", dest="sound",
373
default=False, help=_("Use sound device emulation"))
352
374
fulg.add_option("", "--noapic", action="store_true", dest="noapic",
354
376
help=_("Disables APIC for fully virtualized guest "
380
402
"http://host/path, ftp://host/path)"))
381
403
insg.add_option("", "--pxe", action="store_true", dest="pxe",
382
404
help=_("Boot from the network using the PXE protocol"))
405
insg.add_option("", "--import", action="store_true", dest="import_install",
406
help=_("Build guest around an existing disk image"))
383
407
insg.add_option("", "--livecd", action="store_true", dest="livecd",
384
help=_("Treat the CDROM media is a LiveCD"))
408
help=_("Treat the CD-ROM media as a Live CD"))
385
409
insg.add_option("-x", "--extra-args", type="string", dest="extra",
387
411
help=_("Additional arguments to pass to the kernel "
388
412
"booted from --location"))
390
413
parser.add_option_group(insg)
391
415
stog = OptionGroup(parser, _("Storage Configuration"))
392
416
stog.add_option("", "--disk", type="string", dest="diskopts",
393
417
action="callback", callback=cli.check_before_append,
498
524
options = parse_args()
526
# Default setup options
500
527
cli.setupLogging("virt-install", options.debug)
501
528
cli.set_force(options.force)
502
529
cli.set_prompt(options.prompt)
503
530
conn = cli.getConnection(options.connect)
504
531
capabilities = virtinst.CapabilitiesParser.parse(conn.getCapabilities())
534
# Set up all virt/hypervisor parameters
506
535
if options.fullvirt and options.paravirt:
507
536
fail(_("Can't do both --hvm and --paravirt"))
509
538
if options.fullvirt:
539
req_virt_type = "hvm"
511
540
elif options.paravirt:
541
req_virt_type = "xen"
514
543
# This should force capabilities to give us the most sensible default
517
logging.debug("Requesting virt method '%s'" % (os_type and os_type or \
520
guest = capabilities.guestForOSType(type=os_type, arch=options.arch)
522
msg = _("Unsupported virtualization type '%s' " % (os_type and os_type
525
msg += _("for arch '%s'" % options.arch)
528
os_type = guest.os_type
529
logging.debug("Received virt method '%s'" % os_type)
535
domain = guest.bestDomainType(options.accelerate)
536
htype = domain.hypervisor_type
537
logging.debug("Hypervisor type is '%s'" % htype)
546
logging.debug("Requesting virt method '%s'" % (req_virt_type and
552
capsdomain) = virtinst.CapabilitiesParser.guest_lookup(conn=conn,
553
caps=capabilities, os_type=req_virt_type,
554
arch=options.arch, type=None,
555
accelerated=options.accelerate)
559
virt_type = capsguest.os_type
560
hv_name = capsdomain.hypervisor_type
561
logging.debug("Received virt method '%s'" % virt_type)
562
logging.debug("Hypervisor name is '%s'" % hv_name)
565
# Build the Installer instance
539
566
if options.livecd:
540
installer = virtinst.LiveCDInstaller(type = htype, os_type = os_type,
567
instclass = virtinst.LiveCDInstaller
542
568
elif options.pxe:
543
installer = virtinst.PXEInstaller(type = htype, os_type = os_type,
546
installer = virtinst.DistroInstaller(type = htype, os_type = os_type,
550
guest = virtinst.FullVirtGuest(connection=conn, installer=installer,
553
guest = virtinst.ParaVirtGuest(connection=conn, installer=installer)
569
if options.nonetworks:
570
fail(_("Can't use --pxe with --nonetworks"))
572
instclass = virtinst.PXEInstaller
573
elif options.import_install:
574
instclass = virtinst.ImportInstaller
576
instclass = virtinst.DistroInstaller
577
installer = instclass(type=hv_name, os_type=virt_type, conn=conn)
578
installer.arch = capsguest.arch
581
# Get Guest instance from installer parameters.
582
guest = installer.guest_from_installer()
555
585
# now let's get some of the common questions out of the way
586
if virt_type == "hvm":
556
591
cli.get_name(options.name, guest)
557
592
cli.get_memory(options.memory, guest)
558
593
cli.get_uuid(options.uuid, guest)
559
594
cli.get_vcpus(options.vcpus, options.check_cpu, guest, conn)
560
595
cli.get_cpuset(options.cpuset, guest.memory, guest, conn)
562
597
cli.get_sound(options.sound, guest)
565
600
get_disks(options.file_path, options.diskopts, options.disksize,
566
options.sparse, options.nodisks, guest, hvm, conn)
601
options.sparse, options.nodisks, guest, ishvm, conn)
568
603
# set up network information
569
get_networks(options.mac, options.bridge, options.network, guest)
604
get_networks(options.mac, options.bridge, options.network,
605
options.nonetworks, guest)
571
607
# set up graphics information
572
608
cli.get_graphics(options.vnc, options.vncport, options.nographics,
573
609
options.sdl, options.keymap, guest)
611
# Set host device info
612
cli.get_hostdevs(options.hostdevs, guest)
575
614
get_extraargs(options.extra, guest)
615
if options.distro_type:
616
guest.set_os_type(options.distro_type)
617
if options.distro_variant:
618
guest.set_os_variant(options.distro_variant)
577
620
# and now for the full-virt vs paravirt specific questions
578
621
get_install_media(options.location, options.cdrom, options.pxe,
579
options.livecd, guest, hvm)
580
if not hvm: # paravirt
622
options.livecd, options.import_install, guest, ishvm)
623
if not ishvm: # paravirt
581
624
continue_inst = False
583
626
if options.noacpi:
584
627
guest.features["acpi"] = False
585
628
if options.noapic:
586
629
guest.features["apic"] = False
588
guest.set_os_type(options.os_type)
589
if options.os_variant:
590
guest.set_os_variant(options.os_variant)
591
630
continue_inst = guest.get_continue_inst()
593
632
def show_console(dom):
600
639
return txt_console(dom, options.connect)
641
# There are two main cases we care about:
643
# Scripts: these should specify --wait always, maintaining the
644
# semantics of virt-install exit implying the domain has finished
647
# Interactive: If this is a continue_inst domain, we default to
648
# waiting. Otherwise, we can exit before the domain has finished
649
# installing. Passing --wait will give the above semantics.
653
autoconsole = options.autoconsole
606
657
wait_time = options.wait * 60
608
if wait is True and wait_time == 0:
609
# wait == 0 implies noautoconsole
610
options.autoconsole = False
612
if options.autoconsole is False:
659
# --wait 0 implies --noautoconsole
662
if autoconsole is False:
615
665
conscb = show_console
617
667
progresscb = progress.TextMeter()
619
670
# we've got everything -- try to start the install
671
print _("\n\nStarting install...")
621
def domain_is_shutdown(dom):
626
if state == libvirt.VIR_DOMAIN_SHUTOFF:
629
# If --wait was specified, the dom object we have was looked up
630
# before initially shutting down, which seems to bogus up the
631
# info data (all 0's). So, if it is bogus, assume the domain is
632
# shutdown. We will catch the error later.
633
return state == libvirt.VIR_DOMAIN_NOSTATE and cpu_time == 0
635
print _("\n\nStarting install...")
637
674
start_time = time.time()
642
dom = guest.start_install(conscb, progresscb, wait=(not wait))
644
dom = guest.continue_install(conscb, progresscb,
646
continue_inst = False
651
print _("Guest installation failed")
653
elif dom.info()[0] != libvirt.VIR_DOMAIN_SHUTOFF:
654
# domain seems to be running
656
print _("Domain installation still in progress. Waiting"+\
658
and (_(" %d minutes") % (int(wait_time) / 60))
660
" for domain to shutdown.")
662
if domain_is_shutdown(dom):
663
print _("Domain has shutdown. Continuing.")
665
# Lookup a new domain object incase current
666
# one returned bogus data (see comment in
668
dom = guest.conn.lookupByName(guest.name)
670
raise RuntimeError(_("Could not lookup domain after install: %s" % str(e)))
672
if wait_time < 0 or \
673
((time.time() - start_time) < wait_time):
676
print _("Installation has exceeded specified time"
677
"limit. Exiting application.")
680
print _("Domain installation still in progress. "
681
"You can reconnect to \nthe console to complete "
682
"the installation process.")
687
if not guest.post_install_check():
688
print _("Domain installation does not appear to have been\n successful. If it was, you can restart your domain\n by running 'virsh start %s'; otherwise, please\n restart your installation.") %(guest.name,)
676
# Do first install phase
677
dom = do_install(guest, conscb, progresscb, wait, wait_time,
678
start_time, guest.start_install)
680
# This should be valid even before doing continue install
681
if not guest.post_install_check():
682
print _("Domain installation does not appear to have been\n "
683
"successful. If it was, you can restart your domain\n "
684
"by running 'virsh start %s'; otherwise, please\n "
685
"restart your installation.") % guest.name
689
dom = do_install(guest, conscb, progresscb, wait, wait_time,
690
start_time, guest.continue_install)
691
692
if options.noreboot:
692
print _("Guest installation complete... you can restart your domain\n"
693
"by running 'virsh start %s'") %(guest.name,)
693
print _("Guest installation complete... you can restart your "
694
"domain\nby running 'virsh start %s'") % guest.name
696
# FIXME: Should we say 'installation' complete for livecd, import?
695
697
print _("Guest installation complete... restarting guest.")
697
699
guest.connect_console(conscb)
701
except KeyboardInterrupt, e:
702
guest.terminate_console()
703
print _("Guest install interrupted.")
698
704
except RuntimeError, e:
700
706
except SystemExit, e:
702
708
except Exception, e:
704
print _("Domain installation may not have been\n successful. If it was, you can restart your domain\n by running 'virsh start %s'; otherwise, please\n restart your installation.") %(guest.name,)
710
print (_("Domain installation may not have been\n successful. If it "
711
"was, you can restart your domain\n by running 'virsh start "
712
"%s'; otherwise, please\n restart your installation.") %
716
def domain_is_shutdown(dom):
721
if state == libvirt.VIR_DOMAIN_SHUTOFF:
724
# If --wait was specified, the dom object we have was looked up
725
# before initially shutting down, which seems to bogus up the
726
# info data (all 0's). So, if it is bogus, assume the domain is
727
# shutdown. We will catch the error later.
728
return state == libvirt.VIR_DOMAIN_NOSTATE and cpu_time == 0
730
def do_install(guest, conscb, progresscb, wait, wait_time, start_time,
733
dom = install_func(conscb, progresscb, wait=(not wait))
736
print _("Guest installation failed.")
739
if domain_is_shutdown(dom):
742
# Domain seems to be running
746
timestr = _("%d minutes ") % (int(wait_time) / 60)
748
print _("Domain installation still in progress. Waiting %s"
749
"for domain to complete installation.") % timestr
753
if domain_is_shutdown(dom):
754
print _("Domain has shutdown. Continuing.")
756
# Lookup a new domain object incase current
757
# one returned bogus data (see comment in
759
dom = guest.conn.lookupByName(guest.name)
761
raise RuntimeError(_("Could not lookup domain after "
762
"install: %s" % str(e)))
765
if wait_time < 0 or ((time.time() - start_time) < wait_time):
768
print _("Installation has exceeded specified time limit. "
769
"Exiting application.")
772
print _("Domain installation still in progress. You can reconnect"
773
" to \nthe console to complete the installation process.")
707
778
if __name__ == "__main__":