summaryrefslogtreecommitdiffstats
path: root/loaders/zpxe.rexx
diff options
context:
space:
mode:
Diffstat (limited to 'loaders/zpxe.rexx')
-rw-r--r--loaders/zpxe.rexx261
1 files changed, 261 insertions, 0 deletions
diff --git a/loaders/zpxe.rexx b/loaders/zpxe.rexx
new file mode 100644
index 00000000..3ce6f576
--- /dev/null
+++ b/loaders/zpxe.rexx
@@ -0,0 +1,261 @@
+/* zPXE: REXX PXE Client for System z
+
+zPXE is a PXE client used with Cobbler. It must be run under
+z/VM. zPXE uses TFTP to first download a list of profiles,
+then a specific kernel, initial RAMdisk, and PARM file. These
+files are then punched to start the install process.
+
+zPXE does not require a writeable 191 A disk. Files are
+downloaded to a temporary disk (VDISK).
+
+zPXE can also IPL a DASD disk by default. You can specify the
+default dasd in ZPXE CONF, as well as the hostname of the Cobbler
+server.
+---
+
+Copyright 2006-2009, Red Hat, Inc
+Brad Hinson <bhinson@redhat.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA
+*/
+
+
+/* Defaults */
+
+server = '' /* define server in ZPXE CONF */
+iplDisk = 100 /* overridden by value in ZPXE CONF */
+profilelist = PROFILE LIST T /* VDISK will be defined as T later */
+profiledetail = PROFILE DETAIL T
+zpxeparm = ZPXE PARM T
+zpxeconf = ZPXE CONF T
+config = ZPXE CONF
+
+/* For translating strings to lowercase */
+upper = xrange('A', 'Z')
+lower = xrange('a', 'z')
+
+/* Useful settings normally found in PROFILE EXEC */
+'cp set run on'
+'cp set pf11 retrieve forward'
+'cp set pf12 retrieve'
+
+/* Check for config file */
+if lines(config) > 0 then do
+ inputline = linein(config) /* first line is server hostname/IP */
+ parse var inputline . server .
+ inputline = linein(config) /* second line is DASD disk to IPL */
+ parse var inputline . iplDisk .
+end
+
+/* Define temporary disk (VDISK) to store files */
+'detach ffff' /* detach ffff if present */
+'define vfb-512 as ffff blk 100000' /* 512 byte block size =~ 50 MB */
+queue '1'
+queue 'tmpdsk'
+'format ffff t' /* format VDISK as file mode t */
+
+/* Link TCPMAINT disk for access to TFTP */
+'link tcpmaint 592 592 rr'
+'access 592 e'
+
+/* Query user ID. This is used later to determine:
+ 1. Whether a user-specific PXE profile exists.
+ 2. Whether user is disconnected. If so, IPL the default disk.
+*/
+'pipe cp query' userid() '| var user'
+parse value user with id . dsc .
+userid = translate(id, lower, upper)
+
+/* Check whether a user-specific PXE profile exists.
+ If so, proceed with this. Otherwise, continue and
+ show the system-wide profile menu.
+*/
+call GetTFTP '/s390x/s_'userid 'profile.detail.t'
+
+/* Get user PARM and CONF. If available, will be used later */
+call GetTFTP '/s390x/s_'userid'_parm' 'zpxe.parm.t' /* get parm */
+call GetTFTP '/s390x/s_'userid'_conf' 'zpxe.conf.t' /* get conf */
+
+if lines(profiledetail) > 0 then do
+ vmfclear /* clear screen */
+ call CheckServer /* print server name */
+ say 'Profile 'userid' found'
+ say ''
+ call DownloadBinaries /* download kernel and initrd */
+ say 'Starting install...'
+ say ''
+ call PunchFiles /* punch files to begin install */
+ exit
+end /* if user-specific profile found */
+
+
+/* Download initial profile list */
+call GetTFTP '/s390x/profile_list' 'profile.list.t'
+
+vmfclear /* clear screen */
+call CheckServer /* print server name */
+
+say 'zPXE MENU' /* show menu */
+say '---------'
+
+count = 0
+do while lines(profilelist) > 0 /* display one profile per line */
+ count = count + 1
+ inputline = linein(profilelist)
+ parse var inputline profile.count
+ say count'. 'profile.count
+end
+
+if (count = 0) then
+ say '** Error connecting to server: no profiles found **'
+
+count = count + 1
+say count'. Exit to CMS shell [IPL CMS]'
+say ''
+say ''
+say 'Enter Choice -->'
+say 'or press <Enter> to boot from disk [DASD 'iplDisk']'
+
+/* Check if user is disconnected, indicating
+ logon by XAUTOLOG. In this case, IPL the
+ default disk.
+*/
+if (dsc = 'DSC') then do /* user is disconnected */
+ say 'User disconnected. Booting from DASD 'iplDisk'...'
+ 'cp ipl' iplDisk
+ end
+else do /* user is interactive -> prompt */
+ parse upper pull answer .
+ select
+ when (answer = count)
+ then do
+ say 'Exiting to CMS shell...'
+ exit
+ end
+ when (answer = '') /* IPL by default */
+ then do
+ say 'Booting from DASD 'iplDisk'...'
+ 'cp ipl' iplDisk
+ end
+ when (answer < 0) | (answer > count) /* invalid respone */
+ then do
+ say 'Invalid choice, exiting to CMS shell.'
+ exit
+ end
+ when (answer > 0) & (answer < count) /* valid response */
+ then do
+ call GetTFTP '/s390x/p_'profile.answer 'profile.detail.t'
+
+ /* Don't overwrite user-specific PARM and CONF if available */
+ if lines(zpxeparm) = 0 then
+ call GetTFTP '/s390x/p_'profile.answer'_parm' 'zpxe.parm.t'
+ if lines(zpxeconf) = 0 then
+ call GetTFTP '/s390x/p_'profile.answer'_conf' 'zpxe.conf.t'
+
+ vmfclear /* clear screen */
+ say 'Using profile 'answer' ['profile.answer']'
+ say ''
+ call DownloadBinaries /* download kernel and initrd */
+
+ say 'Starting install...'
+ say ''
+
+ call PunchFiles
+
+ end /* valid answer */
+ otherwise
+ say 'Invalid choice, exiting to CMS shell.'
+ exit
+ end /* Select */
+end
+exit
+
+
+/* Procedure CheckServer
+ Print error message if server is not defined. Otherwise
+ show server name
+*/
+CheckServer:
+
+ if server = '' then
+ say '** Error: No host defined in ZPXE.CONF **'
+ else say 'Connected to server 'server
+ say ''
+
+return 0 /* CheckServer */
+
+
+/* Procedure GetTFTP
+ Use CMS TFTP client to download files
+ path: remote file location
+ filename: local file name
+ transfermode [optional]: 'ascii' or 'octet'
+*/
+GetTFTP:
+
+ parse arg path filename transfermode
+
+ if transfermode <> '' then
+ queue 'mode' transfermode
+ queue 'get 'path filename
+ queue 'quit'
+
+ 'set cmstype ht' /* suppress tftp output */
+ tftp server
+ 'set cmstype rt'
+
+return 0 /* GetTFTP */
+
+
+/* Procedure DownloadBinaries
+ Download kernel and initial RAMdisk. Convert both
+ to fixed record length 80.
+*/
+DownloadBinaries:
+
+ inputline = linein(profiledetail) /* first line is kernel */
+ parse var inputline kernelpath
+ say 'Downloading kernel ['kernelpath']...'
+ call GetTFTP kernelpath 'kernel.img.t' octet
+
+ inputline = linein(profiledetail) /* next line is initrd */
+ parse var inputline initrdpath
+ say 'Downloading initrd ['initrdpath']...'
+ call GetTFTP initrdpath 'initrd.img.t' octet
+
+ /* convert to fixed record length */
+ 'pipe < KERNEL IMG T | fblock 80 00 | > KERNEL IMG T'
+ 'pipe < INITRD IMG T | fblock 80 00 | > INITRD IMG T'
+
+return 0 /* DownloadBinaries */
+
+
+/* Procedure PunchFiles
+ Punch the kernel, initial RAMdisk, and PARM file.
+ Then IPL to start the install process.
+*/
+PunchFiles:
+
+ 'spool punch *'
+ 'close reader'
+ 'purge reader all' /* clear reader contents */
+ 'punch kernel img t (noh' /* punch kernel */
+ 'punch zpxe parm t (noh' /* punch PARM file */
+ 'punch initrd img t (noh' /* punch initrd */
+ 'change reader all keep' /* keep files in reader */
+ 'ipl 00c clear' /* IPL the reader */
+
+return 0 /* PunchFiles */