In zwei meiner allerersten Blogbeiträge, “Installation von CentOS 6.2 mit VirtualBox” und “Installation von Gnome auf CentOS mit VirtualBox”, habe ich CentOS 6.2 mit VirtualBox installiert und das später verwendet, um eine Basebox für Vagrant zu erstellen.
In diesem Beitrag möchte ich zum allerersten Schritt der CentOS-Installation zurückkehren und ihn automatisieren. Glücklicherweise gibt es ein Tool namens VeeWee, das dies und mehr erledigt.
Beim Suchen fand ich auch einen schönen Beitrag über das Erstellen von Vagrant-Boxen mit VeeWee.
Lass uns mit der Installation von VeeWee beginnen:
$ mkdir <some_where>/veewee_test
$ cd <some_where>/veewee_test
$ gem install veewee
$ vagrant basebox templates
Der letzte Befehl listet verfügbare Templates auf. Ein Template ist eine Sammlung vorbereiteter Konfigurationsdateien, damit du nicht von Grund auf anfangen musst. Ich wollte CentOS-6.2-x86_64-minimal. Für CentOS 6.3 würde ich die 6.2-Templates verwenden und sie anpassen.
Bevor ich startete, erstellte ich <some_where>/veewee_test/iso und legte mein ISO-Image hinein (VeeWee würde es sonst automatisch herunterladen).
Dann führte ich aus:
$ vagrant basebox define 'my_cool_basebox' 'CentOS-6.2-x86_64-minimal'
$ vagrant basebox build 'my_cool_basebox'
$ vagrant basebox validate 'my_cool_basebox'
$ vagrant basebox export 'my_cool_basebox'
$ vagrant box add 'my_cool_basebox' 'my_cool_basebox.box'
$ vagrant init 'my_cool_basebox'
$ vagrant up
$ vagrant ssh
Im Grunde ist das alles, was du brauchst. Wie immer lief es nicht so reibungslos wie erwartet. Beim Ausführen von vagrant basebox validate my_cool_basebox bekam ich im letzten Validierungsschritt folgendes:
[Validierungsausgabe unverändert beibehalten]
Scenario: Checking shared folders # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:47
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password | keyfile |
| vagrant | vagrant | vagrant-private.key |
And I run "mount|grep veewee-validation" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
done!
Then I should see "veewee-validation" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
expected: /veewee-validation/
got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)
Failing Scenarios:
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:47 # Scenario: Checking shared folders
7 scenarios (1 failed, 6 passed)
21 steps (1 failed, 20 passed)
0m1.176s
Etwas ging schief. Ich führte die Schritte nach der Validierung fort, nur um zu sehen, was passieren würde, und bekam einen weiteren Fehler bei vagrant up:
$ vagrant up
[default] Importing base box 'my_cool_basebox'...
[default] No guest additions were detected on the base box for this VM! Guest
additions are required for forwarded ports, shared folders, host only
networking, and more. If SSH fails on this machine, please install
the guest additions and repackage the box to continue.
This is not an error message; everything may continue to work properly,
in which case you may ignore this message.
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` v-root /vagrant
Das Einloggen in die Box funktionierte:
$ vagrant ssh
Last login: Tue Jul 24 21:21:33 2012 from 10.0.2.2
[vagrant@localhost ~]$
Also funktionierte es grundsätzlich, aber shared folders scheiterten. Die Build-Ausgabe deutete auf ein Problem bei der Installation der Guest Additions hin:
Building the VirtualBox Guest Additions kernel modules
The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.
The missing package can be probably installed with
yum install kernel-devel-2.6.32-220.el6.x86_64
Building the main Guest Additions module[FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions[ OK ]
Installing the Window System drivers[FAILED]
(Could not find the X.Org or XFree86 Window System.)
dd: writing to `/tmp/clean': No space left on device
15493137+0 records in
15493136+0 records out
7932485632 bytes (7.9 GB) copied, 56.7727 s, 140 MB/s
In postinstall.sh fand ich den Eintrag, der versuchte, genau diesen Paketnamen zu installieren, aber es schlug fehl mit:
No package kernel-devel-2.6.32-220.el6.x86_64 available.
Ich loggte mich in die Vagrant-Box ein und versuchte, manuell zu installieren; das Paket wurde nicht gefunden. Ein Blick in einen alten Blogbeitrag zeigte, dass ich zuvor yum install kernel-devel verwendet hatte, was jetzt funktionierte:
$ yum info kernel-devel
Loaded plugins: fastestmirror, presto
Loading mirror speeds from cached hostfile
* base: ftp.belnet.be
* extras: ftp.belnet.be
* updates: mirror.nucleus.be
Available Packages
Name : kernel-devel
Arch : x86_64
Version : 2.6.32
Release : 279.2.1.el6
Size : 7.6 M
Repo : updates
Summary : Development package for building kernel modules to match the kernel
URL : http://www.kernel.org/
License : GPLv2
Description : This package provides kernel headers and makefiles sufficient to build modules
: against the kernel package.
Ich bearbeitete postinstall.sh, um kernel-devel statt der vollen Versionszeichenkette zu installieren, und führte vagrant basebox build 'my_cool_basebox' erneut aus, bekam aber diesen Fehler:
[Fehler-Traceback beibehalten]
$ vagrant basebox build 'my_cool_basebox'
Shutting down vm my_cool_basebox
Verifying the isofile CentOS-6.2-x86_64-minimal.iso is ok.
Removing step [1] snapshot as it is no more valid
/Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/com/implementer/ffi.rb:106:in `call_and_check': Error in API call to save_settings: 2159738882 (VirtualBox::Exceptions::InvalidVMStateException)
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/com/implementer/ffi.rb:80:in `call_vtbl_function'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/com/implementer/ffi.rb:61:in `call_function'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/com/abstract_interface.rb:145:in `call_function'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/com/abstract_interface.rb:62:in `save_settings'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/vm.rb:422:in `with_open_session'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/virtualbox-0.9.2/lib/virtualbox/snapshot.rb:180:in `destroy'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/session.rb:836:in `transaction'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/session.rb:833:in `each'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/session.rb:833:in `transaction'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/session.rb:267:in `build'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/command/basebox_build.rb:28:in `execute'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/command/basebox.rb:36:in `execute'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/vagrant-1.0.3/lib/vagrant/cli.rb:42:in `execute'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/vagrant-1.0.3/lib/vagrant/environment.rb:167:in `cli'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/vagrant-1.0.3/bin/vagrant:43
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/bin/vagrant:19:in `load'
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/bin/vagrant:19
from /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/bin/ruby_noexec_wrapper:14
muntwissm15146:veewee_test twiss1$ vagrant destroy
[default] VM not created. Moving on...
Ich musste die VM und die zugehörigen Dateien manuell über die VirtualBox-GUI löschen und dann vagrant basebox build 'my_cool_basebox' erneut versuchen.
Während des Builds sah ich auf der Konsole:
---> Package kernel-devel.x86_64 0:2.6.32-279.2.1.el6 will be installed
Also wurde kernel-devel installiert, aber später schlug die Installation der Guest Additions mit der bekannten Meldung fehl:
Uncompressing VirtualBox 4.1.12 Guest Additions for Linux.........
VirtualBox Guest Additions installer
Removing existing VirtualBox DKMS kernel modules[ OK ]
Removing existing VirtualBox non-DKMS kernel modules[ OK ]
Building the VirtualBox Guest Additions kernel modules
The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.
The missing package can be probably installed with
yum install kernel-devel-2.6.32-220.el6.x86_64
Building the main Guest Additions module[FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions[ OK ]
Installing the Window System drivers[FAILED]
(Could not find the X.Org or XFree86 Window System.)
dd: writing to `/tmp/clean': No space left on device
15470233+0 records in
15470232+0 records out
7920758784 bytes (7.9 GB) copied, 47.686 s, 166 MB/s
Ich schaute mir /var/log/vboxadd-install.log in der Box an:
/tmp/vbox.0/Makefile.include.header:97: *** Error: unable to find the sources of your current Linux kernel. Specify KERN_DIR=<directory> and run Make again. Stop.
Creating user for the Guest Additions.
Creating udev rule for the Guest Additions kernel module.
Dann überprüfte ich die Versionen:
$ yum list | grep kernel-devel
kernel-devel.x86_64 2.6.32-279.2.1.el6 updates
$ uname -r
2.6.32-220.el6.x86_64
Die Kernel-Version (uname -r) und die installierte kernel-devel-Version stimmten nicht überein. Ich entfernte wieder alles:
$ vagrant destroy
$ vagrant box remove 'my_cool_basebox'
$ vagrant basebox destroy 'my_cool_basebox'
Ich machte meine Änderungen in postinstall.sh rückgängig und machte eine Änderung in ks.cfg wie auf dieser Seite beschrieben: füge /usr/bin/yum -y install kernel hinzu.
Diesmal zeigte der Build:
---> Package openssl-devel.x86_64 0:1.0.0-20.el6_2.5 will be installed
Und die Installation der Guest Additions war größtenteils erfolgreich:
Uncompressing VirtualBox 4.1.12 Guest Additions for Linux.........
VirtualBox Guest Additions installer
Removing existing VirtualBox DKMS kernel modules[ OK ]
Removing existing VirtualBox non-DKMS kernel modules[ OK ]
Building the VirtualBox Guest Additions kernel modules
Building the main Guest Additions module[ OK ]
Building the shared folder support module[ OK ]
Building the OpenGL support module[FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions[ OK ]
Installing the Window System drivers[FAILED]
(Could not find the X.Org or XFree86 Window System.)
Die Validierung der Box dauerte länger und gab viele Fehler zurück:
[Validierungsausgabe unverändert beibehalten]
$ vagrant basebox validate my_cool_basebox
Feature: vagrant box validation
As a valid vagrant box
I need to comply to a set of rules
Scenario: Checking login # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:5
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run "whoami" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "vagrant" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking sudo # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:12
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run "sudo whoami" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "root" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking ruby # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:19
.undefined method `open_channel' for nil:NilClass (NoMethodError) When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run ". /etc/profile ;ruby --version 2> /dev/null 1> /dev/null; echo $?" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "0" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking gem # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:26
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run ". /etc/profile; gem --version 2> /dev/null 1> /dev/null ; echo $?" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "0" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking chef # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:33
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run ". /etc/profile ;chef-client --version 2> /dev/null 1>/dev/null; echo $?" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "0" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking puppet # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:40
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password |
| vagrant | vagrant |
And I run ". /etc/profile ; puppet --version 2> /dev/null 1>/dev/null; echo $?" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "0" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Scenario: Checking shared folders # /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:47
. When I ssh to "127.0.0.1" with the following credentials: # veewee-0.2.3/validation/features/steps/ssh_steps.rb:56
| username | password | keyfile |
| vagrant | vagrant | vagrant-private.key |
And I run "mount|grep veewee-validation" # veewee-0.2.3/validation/features/steps/ssh_steps.rb:98
undefined method `open_channel' for nil:NilClass (NoMethodError)
Then I should see "veewee-validation" in the output # veewee-0.2.3/validation/features/steps/ssh_steps.rb:167
Failing Scenarios:
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:5 # Scenario: Checking login
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:12 # Scenario: Checking sudo
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:19 # Scenario: Checking ruby
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:26 # Scenario: Checking gem
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:33 # Scenario: Checking chef
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:40 # Scenario: Checking puppet
cucumber /Users/twiss1/.rvm/gems/ruby-1.8.7-p358/gems/veewee-0.2.3/lib/veewee/../../validation/vagrant.feature:47 # Scenario: Checking shared folders
7 scenarios (7 failed)
21 steps (7 failed, 7 skipped, 7 passed)
9m20.915s
Interessanterweise war die VM-Konsole in der GUI schwarz und reagierte nicht. Nach dem Zurücksetzen der VM über die VirtualBox-GUI war die Validierung erfolgreich:
7 scenarios (7 passed)
21 steps (21 passed)
0m1.015s
Ich exportierte die Box. Nach vagrant up erschien der gleiche Shared-Folder-Fehler:
$ vagrant init 'my_cool_basebox'
`Vagrantfile` already exists in this directory. Remove it before
running `vagrant init`.
muntwissm15146:veewee_test twiss1$ vagrant up
[default] Importing base box 'my_cool_basebox'...
[default] No guest additions were detected on the base box for this VM! Guest
additions are required for forwarded ports, shared folders, host only
networking, and more. If SSH fails on this machine, please install
the guest additions and repackage the box to continue.
This is not an error message; everything may continue to work properly,
in which case you may ignore this message.
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` v-root /vagrant
Das ergab keinen Sinn. Ich überprüfte den früheren Exportschritt:
$ vagrant basebox export 'my_cool_basebox'
Vagrant requires the box to be shutdown, before it can export
Sudo also needs to work for user vagrant
Performing a clean shutdown now.
Executing command: sudo /sbin/halt -h -p
........
Machine my_cool_basebox is powered off cleanly
box my_cool_basebox.box already exists
Aha - es exportierte keine neue Box, weil die Datei bereits existierte. Ich entfernte alles und überprüfte das Verzeichnis:
$ vagrant halt
$ vagrant destroy
$ vagrant box remove my_cool_basebox
$ vagrant basebox destroy my_cool_basebox
$ ls -al
Ausgabe:
total 1006480
drwxr-xr-x 8 twiss1 461641192 272 Jul 25 10:07 .
drwxr-xr-x 10 twiss1 461641192 340 Jul 24 17:27 ..
-rw-r--r--@ 1 twiss1 461641192 6148 Jul 24 17:30 .DS_Store
-rw-r--r-- 1 twiss1 461641192 14 Jul 24 17:28 .rvmrc
-rw-r--r-- 1 twiss1 461641192 3990 Jul 24 21:26 Vagrantfile
drwxr-xr-x 3 twiss1 461641192 102 Jul 24 18:05 definitions
drwxr-xr-x 4 twiss1 461641192 136 Jul 24 17:30 iso
-rw-r--r-- 1 twiss1 461641192 515301376 Jul 24 21:24 my_cool_basebox.box
Ich hatte also die ganze Zeit mit einer alten Box-Datei gearbeitet. Um das zu beheben:
$ rm my_cool_basebox.box
$ vagrant basebox build 'my_cool_basebox'
Die Validierung produzierte wieder viele Fehler und die VirtualBox-GUI-Konsole war schwarz. Das Zurücksetzen der VM behob es wieder, und danach lief alles reibungslos: Validierung, Export und Starten der Box.
$ vagrant box add 'my_cool_basebox' 'my_cool_basebox.box'
[vagrant] Downloading with Vagrant::Downloaders::File...
[vagrant] Copying box to temporary location...
[vagrant] Extracting box...
[vagrant] Verifying box...
[vagrant] Cleaning up downloaded box...
muntwissm15146:veewee_test twiss1$ vagrant up
[default] Importing base box 'my_cool_basebox'...
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
Einloggen:
$ vagrant ssh
Last login: Wed Jul 25 09:07:03 2012 from 10.0.2.2
Endlich!
Aber ich habe noch einige offene Fragen:
- Wie entferne oder lösche ich alles vollständig, wenn ich die gesamte Prozedur erneut starten möchte?
- Warum ist die VirtualBox-Konsole manchmal schwarz und die Validierung schlägt dann fehl?
Fertig für heute!