Upgrading to Beaker 0.9¶
These notes describe the steps needed to upgrade your Beaker installation from version 0.8.2 to version 0.9.3.
For older upgrade instructions, refer to the obsolete SchemaUpgrades directory in Beaker’s source tree.
Database changes¶
New distros schema¶
This upgrade requires that all existing distros be re-imported into Beaker. Ensure that you have an up-to-date database backup before proceeding.
-- distro becomes distro_tree
RENAME TABLE distro TO distro_tree;
-- create distro table from existing distro_trees
CREATE TABLE distro
(id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
osversion_id INT NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE (name),
CONSTRAINT distro_osversion_id_fk
FOREIGN KEY (osversion_id) REFERENCES osversion (id))
ENGINE=InnoDB
SELECT NULL AS id, name, MAX(osversion_id) AS osversion_id, UTC_TIMESTAMP() AS date_created
FROM distro_tree
GROUP BY name;
ALTER TABLE distro_tree
DROP FOREIGN KEY distro_tree_ibfk_1, -- breed_id fk
DROP FOREIGN KEY distro_tree_ibfk_3, -- osversion_id fk
DROP install_name,
DROP breed_id,
DROP osversion_id,
DROP virt,
MODIFY arch_id INT NOT NULL,
MODIFY date_created DATETIME NOT NULL,
ADD distro_id INT DEFAULT NULL AFTER id,
ADD ks_meta TEXT AFTER variant,
ADD kernel_options TEXT AFTER ks_meta,
ADD kernel_options_post TEXT AFTER kernel_options;
-- If your schema is old, it might still contain an obsolete "method" column as well:
--ALTER TABLE distro_tree DROP method;
UPDATE distro_tree
INNER JOIN distro ON distro_tree.name = distro.name
SET distro_tree.distro_id = distro.id;
ALTER TABLE distro_tree
DROP name,
MODIFY distro_id INT NOT NULL,
ADD CONSTRAINT distro_tree_distro_id_fk
FOREIGN KEY (distro_id) REFERENCES distro (id);
-- In the following upgrades, we merge duplicate distro_trees into the
-- lowest matching id, so that we can clean them up below and add a
-- uniqe constraint.
-- distro_activity becomes distro_tree_activity, with duplicates merged
RENAME TABLE distro_activity TO distro_tree_activity;
ALTER TABLE distro_tree_activity
ADD distro_tree_id INT DEFAULT NULL AFTER distro_id,
ADD CONSTRAINT distro_tree_activity_distro_tree_id_fk
FOREIGN KEY (distro_tree_id) REFERENCES distro_tree (id);
UPDATE distro_tree_activity
INNER JOIN distro_tree ON distro_tree_activity.distro_id = distro_tree.id
-- this is the least-row-per-group trick
INNER JOIN (
SELECT MIN(id) AS id, distro_id, arch_id, variant
FROM distro_tree
GROUP BY distro_id, arch_id, variant) AS x
ON x.distro_id = distro_tree.distro_id
AND x.arch_id = distro_tree.arch_id
AND x.variant <=> distro_tree.variant
SET distro_tree_activity.distro_tree_id = x.id;
ALTER TABLE distro_tree_activity
DROP FOREIGN KEY distro_tree_activity_ibfk_2, -- distro_id fk
DROP distro_id;
UPDATE activity
SET type = 'distro_tree_activity'
WHERE type = 'distro_activity';
-- recipe.distro_id becomes recipe.distro_tree_id
ALTER TABLE recipe
ADD distro_tree_id INT DEFAULT NULL AFTER distro_id,
ADD CONSTRAINT recipe_distro_tree_id_fk
FOREIGN KEY (distro_tree_id) REFERENCES distro_tree (id);
UPDATE recipe
INNER JOIN distro_tree ON recipe.distro_id = distro_tree.id
INNER JOIN (
SELECT MIN(id) AS id, distro_id, arch_id, variant
FROM distro_tree
GROUP BY distro_id, arch_id, variant) AS x
ON x.distro_id = distro_tree.distro_id
AND x.arch_id = distro_tree.arch_id
AND x.variant <=> distro_tree.variant
SET recipe.distro_tree_id = x.id;
ALTER TABLE recipe
DROP FOREIGN KEY recipe_ibfk_3, -- distro_id fk
DROP distro_id;
-- system.reprovision_distro_id becomes system.reprovision_distro_tree_id
ALTER TABLE system
ADD reprovision_distro_tree_id INT DEFAULT NULL AFTER reprovision_distro_id,
ADD CONSTRAINT system_reprovision_distro_tree_id_fk
FOREIGN KEY (reprovision_distro_tree_id) REFERENCES distro_tree (id);
UPDATE system
INNER JOIN distro_tree ON system.reprovision_distro_id = distro_tree.id
INNER JOIN (
SELECT MIN(id) AS id, distro_id, arch_id, variant
FROM distro_tree
GROUP BY distro_id, arch_id, variant) AS x
ON x.distro_id = distro_tree.distro_id
AND x.arch_id = distro_tree.arch_id
AND x.variant <=> distro_tree.variant
SET system.reprovision_distro_tree_id = x.id;
ALTER TABLE system
DROP FOREIGN KEY system_ibfk_1, -- reprovision_distro_id fk
DROP reprovision_distro_id;
-- this table is replaced by distro_tree_lab_controller_map
DROP TABLE distro_lab_controller_map;
-- move tags from distro_tree to distro
CREATE TABLE distro_tag_map_new
(distro_id INT NOT NULL,
distro_tag_id INT NOT NULL,
PRIMARY KEY (distro_id, distro_tag_id),
CONSTRAINT distro_tag_map_distro_id_fk
FOREIGN KEY (distro_id) REFERENCES distro (id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT distro_tag_map_distro_tag_id_fk
FOREIGN KEY (distro_tag_id) REFERENCES distro_tag (id)
ON UPDATE CASCADE ON DELETE CASCADE)
ENGINE=InnoDB
SELECT DISTINCT distro.id AS distro_id, distro_tag_map.distro_tag_id
FROM distro_tag_map
INNER JOIN distro_tree ON distro_tag_map.distro_id = distro_tree.id
INNER JOIN distro ON distro_tree.distro_id = distro.id;
DROP TABLE distro_tag_map;
RENAME TABLE distro_tag_map_new TO distro_tag_map;
-- remove the duplicate distro_trees
DELETE FROM distro_tree
USING distro_tree
INNER JOIN (
SELECT MIN(id) AS id, distro_id, arch_id, variant
FROM distro_tree
GROUP BY distro_id, arch_id, variant) AS x
ON x.distro_id = distro_tree.distro_id
AND x.arch_id = distro_tree.arch_id
AND x.variant <=> distro_tree.variant
WHERE distro_tree.id != x.id;
ALTER TABLE distro_tree
ADD UNIQUE (distro_id, arch_id, variant);
-- we don't store breed anymore
DROP TABLE breed;
-- these are unused
ALTER TABLE lab_controller
DROP distros_md5,
DROP systems_md5;
Then run beaker-init to create the new distro tables.
Finally, import distros using the beaker-import command on each lab controller.
Provision via the command queue¶
Run the following SQL:
ALTER TABLE command_queue
ADD delay_until DATETIME AFTER task_id,
ADD distro_tree_id INT NULL,
ADD kernel_options TEXT NULL,
ADD CONSTRAINT command_queue_distro_tree_id_fk
FOREIGN KEY (distro_tree_id)
REFERENCES distro_tree (id);
ALTER TABLE recipe
ADD rendered_kickstart_id INT NULL AFTER system_id,
ADD CONSTRAINT recipe_rendered_kickstart_id_fk
FOREIGN KEY (rendered_kickstart_id)
REFERENCES rendered_kickstart (id);
Cobbler credentials are not needed¶
Run the following SQL:
ALTER TABLE lab_controller
DROP username,
DROP password;
Expand CPU flag column (#%s782284)¶
Run the following SQL:
ALTER TABLE cpu_flag
MODIFY flag VARCHAR(255) DEFAULT NULL;
To roll back:
ALTER TABLE cpu_flag
MODIFY flag VARCHAR(10) DEFAULT NULL;
Remove activity rows for deleted groups (#%s840724)¶
This will remove rows that fail the new non-NULLable constraint of group_activity.group_id. Run the following SQL:
DELETE FROM group_activity WHERE group_id IS NULL;
DELETE FROM activity WHERE type = 'group_activity'
AND id NOT IN (SELECT id FROM group_activity);
ALTER TABLE group_activity
MODIFY group_id int(11) NOT NULL;
We can only rollback our group_activity.group_id modification. To roll back:
ALTER TABLE group_activity
MODIFY group_id int(11) NULL;
ARM support in beaker-provision (#%s841969)¶
Run the following SQL:
ALTER TABLE system
ADD kernel_type_id INT(11) NOT NULL;
UPDATE system set kernel_type_id = (SELECT id FROM kernel_type WHERE kernel_type = 'default');
ALTER TABLE system
ADD CONSTRAINT system_kernel_type_id_fk
FOREIGN KEY (kernel_type_id) REFERENCES kernel_type (id);
ALTER TABLE distro_tree_image
MODIFY image_type enum('kernel','initrd','live','uimage','uinitrd') NOT NULL,
ADD kernel_type_id INT(11) NOT NULL;
UPDATE distro_tree_image set kernel_type_id = (SELECT id FROM kernel_type WHERE kernel_type = 'default');
ALTER TABLE distro_tree_image
ADD CONSTRAINT distro_tree_image_kernel_type_id_fk
FOREIGN KEY (kernel_type_id) REFERENCES kernel_type (id),
DROP PRIMARY KEY,
ADD PRIMARY KEY (distro_tree_id, image_type,kernel_type_id);
To roll back:
ALTER TABLE system
DROP kernel_type_id,
DROP FOREIGN KEY system_kernel_type_id_fk;
ALTER TABLE distro_tree_image
DROP PRIMARY KEY,
DROP kernel_type_id,
DROP FOREIGN KEY distro_tree_image_kernel_type_id_fk,
ADD PRIMARY KEY (distro_tree_id, image_type);
DROP TABLE kernel_type;
Migrating Cobbler configuration¶
Default root password for installed systems¶
Since version 0.8.2 the root password for installed systems can be set globally by the Beaker administrator, as well as individually by each user. However if no password was set, the Cobbler default root password was inherited from the default_password_crypted setting in /etc/cobbler/settings.
If you have not already set a global root password in Beaker, you may want to set it to the same password configured in Cobbler.
Default kernel options¶
Cobbler allows site-wide default kernel options to be configured in the kernel_options setting in /etc/cobbler/settings. If you have modified these, you may want to apply the same defaults in Beaker by setting beaker.kernel_options in /etc/beaker/server.cfg.
In addition, Cobbler has default kernel options specifically for S/390 systems in the kernel_options_s390x setting, which default to:
RUNKS=1 ramdisk_size=40000 root=/dev/ram0 ro ip=off vnc
If you are the lucky owner of an S/390 mainframe you should set these kernel options in the Install Options tab for your S/390 systems.
Install options for Cobbler distros¶
If you have set kickstart metadata, kernel options, or post-install kernel options for any distros in Cobbler (for example using cobbler distro edit) you will need to find the equivalent distro tree in Beaker’s web UI and set the options there. The format and meaning of the install options in Beaker are the same as in Cobbler.
Power scripts¶
When executing power commands, Beaker uses shell scripts which are based on Cobbler’s power templates which are installed in /etc/cobbler/power. If you have customised any of Cobbler’s power templates you may need to add a custom Beaker power script with the same modifications. Refer to Customizing power commands in the Administration Guide.
Note that Beaker uses shell scripts rather than Cheetah templates for power commands, even though the shell scripts look very similar because the variable names are the same. You can examine the default scripts in /usr/lib/python2.6/site-packages/bkr/labcontroller/power-scripts for inspiration.
Netboot config files¶
Beaker does not use templates for generating bootloader configs when provisioning a system (Cobbler’s /etc/cobbler/pxe/pxesystem.template etc). Customizing these configs is not supported.
Unlike Cobbler, Beaker does not manage the default bootloader config ($TFTP_ROOT/pxelinux.cfg/default, and equivalent files for other bootloaders). You can continue to let Cobbler put its PXE menu here, or you can manage this file by hand. Beaker’s only requirement for automated provisioning is that it must default to local booting with a sensible timeout (the Cobbler PXE menu does this).
Snippets¶
Snippets are now located on the Beaker server (rather than the lab controller), under /etc/beaker/snippets.
Beaker uses Jinja2 for templating, so templates will need to be rewritten. Refer to the Jinja2 documentation for details of the template syntax, and to Customizing kickstarts in the Administration Guide for details about the Beaker specifics.
For your convenience, some common Cobbler template constructs are shown below, along with their equivalent in Beaker.
Accessing a variable:
$getVar('ondisk', '')
{{ ondisk }}
Looping:
#set _devices = $getVar('scsidevices', '').split(',')
#for $device in $_devices:
device $device
#end for
{% for device in scsidevices|split(',') %}
device {{ device }}
{% endfor %}
Conditional on distro version:
#if $os_version == "rhel3"
#set $yum = "yum-2.2.2-1.rhts.EL3.noarch.rpm"
#end if
{% if distro is osmajor('RedHatEnterpriseLinux3') %}
{% set yum = 'yum-2.2.2-1.rhts.EL3.noarch.rpm' %}
{% endif %}
Other Cobbler system management features¶
Cobbler’s func integration, managed config files, and RHN registration features are incompatible with Beaker.
DHCP and DNS services are outside the scope of Beaker, so if you are using Cobbler to manage these in the lab then you can continue to do so. However, if you are relying on Cobbler’s network config scripts when provisioning systems (that is, the pre_install_network_config, network_config, and post_install_network_config snippets) you must migrate this configuration to DHCP instead.
If a system has particular network configuration needs not covered by DHCP, you can add a per-system snippet for it as appropriate: system_pre for pre-installation scripts, network for Anaconda network commands, or system_post for post-installation scripts. Refer to Customizing kickstarts in the Administration Guide for details.