Dec 27

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

Ordinarily the demos I create use desktop backgrounds to guide the demonstration flow by “behaving” in a manner similar to a slideshow. When I double-click and “next” arrow/icon the desktop background is replaced by the “next” desktop background, or by “previous” desktop background if I double-click the “previous” arrow/icon. This will be discussed and shown in another article in this series.

For this to work effectively the standard desktop icons provided by Gnome must not be visible. Rather than trying to find a way of deleting these icons I hide them, which is possible in gnome 2.

Similarly, the top and bottom tool bars, which clearly show the Linux Gnome origin of the desktop, could usefully be hidden to eliminate distraction if top panel menus are not used in the demonstration and if bottom panel objects are not used in the demonstration. This, too, is possible.

In this post I discuss how to script hiding the standard desktop icons and how to script configuration of top and bottom panels so that they are able to be hidden.

Pre-Requisites

This article assumes that the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image is available but it is expected that pretty much any VirtualBox Linux disk will do just as well so long as it runs Gnome 2 desktop.

Hide desktop icons

Our gnome desktop has a bunch of icons which will get in the way if we use a specific set of backgrounds to guide the demonstration.

Let’s create a script that will make standard desktop icons disappear

cat <<-'EODECK' > /media/sf_distros/scripts/014_hide_desktop_icons.sh

gconftool-2 -s -t bool /apps/nautilus/desktop/home_icon_visible "false"
gconftool-2 -s -t bool /apps/nautilus/desktop/volumes_visible "false"
gconftool-2 -s -t bool /apps/nautilus/desktop/trash_icon_visible "false"
gconftool-2 -s -t bool /apps/nautilus/desktop/computer_icon_visible "false"
EODECK
chmod ug+x /media/sf_distros/scripts/014_hide_desktop_icons.sh

Let’s execute the script to hide desktop icons

/bin/bash -v /media/sf_distros/scripts/014_hide_desktop_icons.sh

The icons are now invisible.

Executing commands in the script with “true” rather than “false” will make the icons re-appear.

Make top and bottom panels hideable

Our gnome desktop has a visible top panel and a visible bottom panel, which tell anyone somewhat familiar with IT that what they see is a Linux Gnome desktop.

This might be distracting if we don’t use top panel menus or bottom panel objects in our demonstration.

Ideally, since we might want to interact with the menus and objects when we are building the demo or preparing for a demo, the top and bottom panels should be accessible on demand.

The script shown below will add hide/show “button” at the extreme right of each panel. This button will be visible regardless of whether the panel is hidden or shown.

Let’s create and execute a script that will make top bar and bottom bar hideable.

cat <<-'EODECK' > /media/sf_distros/scripts/015_make_gnome_panels_hideable.sh
gconftool-2 -s -t bool /apps/panel/toplevels/top_panel/enable_buttons true
gconftool-2 -s -t bool /apps/panel/toplevels/top_panel/auto_hide false
gconftool-2 -s -t bool /apps/panel/toplevels/bottom_panel/enable_buttons true
EODECK
chmod gu+x /media/sf_distros/scripts/015_make_gnome_panels_hideable.sh

Let’s execute the script

/bin/bash /media/sf_distros/scripts/015_make_gnome_panels_hideable.sh

Note the middle line in the script – auto_hide false. If you change false to true then the top panel will auto-hide and will appear when the cursor is moved up to the top of the screen.

Give it a try and see how it works.

Add to initial bulk configuration script

It is expected that the image being configured a bit at a time in this series of articles will be created more than once for different purposes. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# update hide desktop icons
/bin/bash -v /media/sf_distros/scripts/014_hide_desktop_icons.sh

# make desktop panels hideable
/bin/bash -v /media/sf_distros/scripts/015_make_gnome_panels_hideable.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh

 

Dec 24

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

Ordinarily I create a dynamic virtual disk with the potential to grow to perhaps 120Gb In size. Since the disk I ordinarily create is dynamic the host disk space it needs gets allocated as needed, thus the disk may never actually grow to the defined size.

There may be circumstances, for example if one needs to create a raw disk for import into 3rd party virtualisation platform, when the size of the disk must be reduced to conform to externally imposed constraints.

In this post I discuss how a virtual disk with a working installation can be reduced in size while remaining useable. This will be accomplished using the virtual disk which was built up in this series of articles.

Pre-Requisites

This article assumes that the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image is available but it is expected that pretty much any VirtualBox Linux disk will do just as well.

The instructions should work in other RedHat 6-like OS’ and OS versions.

Discussion

Let’s assume that we need to shrink a virtual disk of a configured Virtual Box Virtual Machine. This disk will be partitioned, if you are using the disk image created in the series of articles of which this one is a part, into two partitions. The partitions are the swap partition, 8GB in size, at the beginning of the disk, and the data partition, occupying the rest of the disk.

Boot the demo image. log in, and execute the following command in a terminal window to see how the disk is partitioned:

lsblk

I see:

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 117.2G  0 disk
??sda1   8:1    0     8G  0 part [SWAP]
??sda2   8:2    0 109.2G  0 part /
sr0     11:0    1  1024M  0 rom

There is one disk device, sda, which has 117.2GB of useable space, which has two partitions – sda1 is a swap partition of 8GB and sda2 is a file system partition of 102.2GB.

Let’s find out how much of the file system partition is actually used:

df -h

I see:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       108G  5.8G   97G   6% /
tmpfs           1.9G   80K  1.9G   1% /dev/shm

Let’s say that we don’t expect to use more than another 20GB so we can see that if we shrink the partition to around 30GB we will have plenty of room for what we expect to be doing.

The process involves shrinking the source disk’s partition and cloning the disk with a smaller partition, then discarding the original disk and using the smaller disk in its place.

To accomplish the task we will go through the following steps:

  1. Export the VM to a .ova archive – this will cause any differencing disks / snapshots to be applied and will give us a complete source virtual disk in the archive – this will also serve as a backup if we have issues shrinking the disk
  2. Import the exported VM image to create a new VM – we need a VM to manipulate the source virtual disk so we will use the one created by the import
  3. Create a blank, 40GB Virtual Disk to use as target
  4. Attach the new blank disk to the new VM – this will give us access to both the source and the target disks – source to shrink and target to copy the shrunk partition to it
  5. Boot from GParted Live CD – this will give us access to the GParted tools and to the virtual disk which to shrink
  6. Shrink the source disk file system partition to 30GB
  7. Partition the target disk
  8. Copy source disk’s swap partition to the target disk
  9. Copy source disk’s file system partition to the target disk
  10. Reboot with the CentOS Install disk in the DVD drive to have access to system rescue facilities
  11. Fix the Grub Bootloader
  12. Reboot with just the target disk attached

Resources

The resources we need are the Centos install ISO, which we should have from our earlier work, http://centos.mirror.digitalpacific.com.au/6.8/isos/x86_64/CentOS-6.8-x86_64-bin-DVD1.iso and GParted ISO, from http://downloads.sourceforge.net/project/gparted/gparted-live-stable/0.27.0-1/gparted-live-0.27.0-1-i686.iso?r=http%3A%2F%2Fgparted.sourceforge.net%2F&ts=1482278033&use_mirror=internode

Assuming that you don’t have the ISOs, in a terminal widow, execute the following commands:

wget http://centos.mirror.digitalpacific.com.au/6.8/isos/x86_64/CentOS-6.8-x86_64-bin-DVD1.iso -O /media/sf_distros/CentOS-6.8-x86_64-bin-DVD1.iso

wget http://downloads.sourceforge.net/project/gparted/gparted-live-stable/0.27.0-1/gparted-live-0.27.0-1-i686.iso -O /media/sf_distros/gparted-live-0.27.0-1-i686.iso

Export Virtual Disk

Let’s find out how our “demo” Virtual Machine is configured (assuming our host is a Windows OS – adjust as required if your host is a Unix-like OS).

@rem see what the VM looks like
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% showvminfo "demo"

I see

Name:            demo
Groups:          /
Guest OS:        Red Hat (64-bit)
UUID:            a9a4e4a6-77d3-4c7c-abb1-024291c8bbf4
Config file:     d:\VirtualBoxDisks\demo\demo.vbox
Snapshot folder: d:\VirtualBoxDisks\demo\Snapshots
Log folder:      d:\VirtualBoxDisks\demo\Logs
Hardware UUID:   a9a4e4a6-77d3-4c7c-abb1-024291c8bbf4
Memory size:     4096MB
Page Fusion:     off
VRAM size:       128MB
CPU exec cap:    100%
HPET:            off
Chipset:         piix3
Firmware:        BIOS
Number of CPUs:  3
PAE:             on
Long Mode:       on
Triple Fault Reset: off
APIC:            on
X2APIC:          on
CPUID Portability Level: 0
CPUID overrides: None
Boot menu mode:  message and menu
Boot Device (1): DVD
Boot Device (2): HardDisk
Boot Device (3): Not Assigned
Boot Device (4): Not Assigned
ACPI:            on
IOAPIC:          on
BIOS APIC mode:  APIC
Time offset:     0ms
RTC:             UTC
Hardw. virt.ext: on
Nested Paging:   on
Large Pages:     on
VT-x VPID:       on
VT-x unr. exec.: on
Paravirt. Provider: Default
Effective Paravirt. Provider: KVM
State:           running (since 2016-12-23T23:48:11.544000000)
Monitor count:   1
3D Acceleration: on
2D Video Acceleration: off
Teleporter Enabled: off
Teleporter Port: 0
Teleporter Address:
Teleporter Password:
Tracing Enabled: off
Allow Tracing to Access VM: off
Tracing Configuration:
Autostart Enabled: off
Autostart Delay: 0
Default Frontend:
Storage Controller Name (0):            IDE
Storage Controller Type (0):            PIIX4
Storage Controller Instance Number (0): 0
Storage Controller Max Port Count (0):  2
Storage Controller Port Count (0):      2
Storage Controller Bootable (0):        on
IDE (0, 0): d:\VirtualBoxDisks\demo\Snapshots\{c8e1a17f-6271-483f-870f-3a691a93a635}.vdi (UUID: c8e1a17f-6271-483f-870f-3a691a93a635)
IDE (1, 0): Empty
NIC 1:           MAC: 08002753AFFF, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 10000 Mbps
, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
NIC 1 Settings:  MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64)
NIC 2:           disabled
NIC 3:           disabled
NIC 4:           disabled
NIC 5:           disabled
NIC 6:           disabled
NIC 7:           disabled
NIC 8:           disabled
Pointing Device: PS/2 Mouse
Keyboard Device: PS/2 Keyboard
UART 1:          disabled
UART 2:          disabled
UART 3:          disabled
UART 4:          disabled
LPT 1:           disabled
LPT 2:           disabled
Audio:           enabled (Driver: DSOUND, Controller: AC97, Codec: STAC9700)
Clipboard Mode:  Bidirectional
Drag and drop Mode: disabled
Session name:    GUI/Qt
Video mode:      1600x900x32 at 0,0 enabled
VRDE:            disabled
USB:             enabled
EHCI:            enabled
XHCI:            disabled

USB Device Filters:
<none>

Available remote USB devices:
<none>

Currently Attached USB Devices:
<none>

Bandwidth groups:  <none>

Shared folders:
Name: 'distros', Host path: 'O:\DemoBuilding\Distros' (machine mapping), writable
VRDE Connection:    not active
Clients so far:     0

Video capturing:    not active
Capture screens:    0
Capture file:       d:\VirtualBoxDisks\demo\demo.webm
Capture dimensions: 1024x768
Capture rate:       512 kbps
Capture FPS:        25

Guest:

Configured memory balloon size:      0 MB
OS type:                             Linux26_64
Additions run level:                 2
Additions version:                   5.1.8 r111374

Guest Facilities:

Facility "VirtualBox Base Driver": active/running (last update: 2016/12/23 23:48:22 UTC)
Facility "VirtualBox System Service": active/running (last update: 2016/12/23 23:48:31 UTC)
Facility "Seamless Mode": active/running (last update: 2016/12/23 23:48:22 UTC)
Facility "Graphics Mode": active/running (last update: 2016/12/23 23:48:22 UTC)

Snapshots:
   Name: v1.0.0 Baseline - CentOS 6.8 Installed (UUID: dedfb09a-965b-42e5-898e-e2d207dca628)
   Description:
v1.0.0 Baseline - CentOS 6.8 Installed
      Name: v1.0.8 Update DHCP address in /etc/hosts at boot (UUID: 6473898e-c9e4-4d60-8c5e-5e16187e5125)
         Name: v1.0.9 Script adding a new gnome-terminal profile (UUID: 228ef39e-81ac-49ff-a5ee-7be9977899b7)
            Name: v1.1.0 Installed CentOS 6.8 and configured root environment (UUID: 4ddc0470-b586-44ad-908e-2a7af518de43)
               Name: Snapshot 1 (UUID: 5e5463f0-7fbb-472d-8473-bca3924e19f7)
               Name: v1.1.1 Script creating a new demo user (UUID: 1089b3c9-8e93-4d1c-a480-0eb745275915) *

Note that the disk has a bunch of snapshots so we need to export the machine to “flatten” them out into a complete virtual disk in a single file.

Make sure the source virtual machine is shut down.

Assuming that we use the directory on Windows which we use for software distributions, let’s create a directory for the export and export the virtual machine:

@rem create output directory and export disk image
mkdir O:\DemoBuilding\Distros\demo_export
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% export "demo" --output O:\DemoBuilding\Distros\demo_export\demo_export.ova --ovf20 --manifest --options manifest,nomacs

I see

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Successfully exported 1 machine(s).

Import the exported VM

Let’s find out how the Virtual Machine export looks like (assuming our host is a Windows OS – adjust as required if your host is a Unix-like OS).

@rem import ova as --dry-run to see what a real import would look like
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% import O:\DemoBuilding\Distros\demo_export\demo_export.ova  --dry-run

I see

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting O:\DemoBuilding\Distros\demo_export\demo_export.ova...
OK.
Disks:
  vmdisk1       0       -1      http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized demo_export-disk1.vmdk  -1
-1

Virtual system 0:
 0: Suggested OS type: "RedHat_64"
    (change with "--vsys 0 --ostype <type>"; use "list ostypes" to list all possible values)
 1: Suggested VM name "demo_1"
    (change with "--vsys 0 --vmname <name>")
 2: Number of CPUs: 3
    (change with "--vsys 0 --cpus <n>")
 3: Guest memory: 4096 MB
    (change with "--vsys 0 --memory <MB>")
 4: Sound card (appliance expects "", can change on import)
    (disable with "--vsys 0 --unit 4 --ignore")
 5: USB controller
    (disable with "--vsys 0 --unit 5 --ignore")
 6: Network adapter: orig NAT, config 3, extra slot=0;type=NAT
 7: CD-ROM
    (disable with "--vsys 0 --unit 7 --ignore")
 8: IDE controller, type PIIX4
    (disable with "--vsys 0 --unit 8 --ignore")
 9: IDE controller, type PIIX4
    (disable with "--vsys 0 --unit 9 --ignore")
10: Hard disk image: source image=demo_export-disk1.vmdk, target path=o:\VirtualBoxDisks\demo_1\demo_export-disk1.vmdk, controller=8;channel
=0
    (change target path with "--vsys 0 --unit 10 --disk path";
    disable with "--vsys 0 --unit 10 --ignore")

Note that the name the imported VM would be give would be demo_1. This is not what we want so we will tell import to change it to demo2. There are a bunch of other settings that can be changed during import. The Virtual Box User Manual provides information on these options.

Let’s import the VM with the new name.

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% import O:\DemoBuilding\Distros\demo_export\demo_export.ova --vsys 0 --vmname "demo2" --description "Shrunk VM"

I see:

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting O:\DemoBuilding\Distros\demo_export\demo_export.ova...
OK.
Disks:
  vmdisk1       0       -1      http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized       demo_export-disk1.vmdk  -1
-1

Virtual system 0:
 0: Suggested OS type: "RedHat_64"
    (change with "--vsys 0 --ostype <type>"; use "list ostypes" to list all possible values)
 1: VM name specified with --vmname: "demo2"
 2: Number of CPUs: 3
    (change with "--vsys 0 --cpus <n>")
 3: Guest memory: 4096 MB
    (change with "--vsys 0 --memory <MB>")
 4: Sound card (appliance expects "", can change on import)
    (disable with "--vsys 0 --unit 4 --ignore")
 5: USB controller
    (disable with "--vsys 0 --unit 5 --ignore")
 6: Network adapter: orig NAT, config 3, extra slot=0;type=NAT
 7: CD-ROM
    (disable with "--vsys 0 --unit 7 --ignore")
 8: IDE controller, type PIIX4
    (disable with "--vsys 0 --unit 8 --ignore")
 9: IDE controller, type PIIX4
    (disable with "--vsys 0 --unit 9 --ignore")
10: Hard disk image: source image=demo_export-disk1.vmdk, target path=o:\VirtualBoxDisks\demo_1\demo_export-disk1.vmdk, controller=8;channel
=0
    (change target path with "--vsys 0 --unit 10 --disk path";
    disable with "--vsys 0 --unit 10 --ignore")
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Successfully imported the appliance.

Let’s see what the new VM looks like

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% showvminfo "demo2"

I see:

Name:            demo2
Groups:          /
Guest OS:        Red Hat (64-bit)
UUID:            76bd82ae-c445-41a8-88d9-1c75ef422b89
Config file:     o:\VirtualBoxDisks\demo2\demo2.vbox
Snapshot folder: o:\VirtualBoxDisks\demo2\Snapshots
Log folder:      o:\VirtualBoxDisks\demo2\Logs
Hardware UUID:   76bd82ae-c445-41a8-88d9-1c75ef422b89
Memory size:     4096MB
Page Fusion:     off
VRAM size:       128MB
CPU exec cap:    100%
HPET:            off
Chipset:         piix3
Firmware:        BIOS
Number of CPUs:  3
PAE:             on
Long Mode:       on
Triple Fault Reset: off
APIC:            on
X2APIC:          on
CPUID Portability Level: 0
CPUID overrides: None
Boot menu mode:  message and menu
Boot Device (1): DVD
Boot Device (2): HardDisk
Boot Device (3): Not Assigned
Boot Device (4): Not Assigned
ACPI:            on
IOAPIC:          on
BIOS APIC mode:  APIC
Time offset:     0ms
RTC:             UTC
Hardw. virt.ext: on
Nested Paging:   on
Large Pages:     on
VT-x VPID:       on
VT-x unr. exec.: on
Paravirt. Provider: Default
Effective Paravirt. Provider: KVM
State:           powered off (since 2016-12-24T00:27:28.000000000)
Monitor count:   1
3D Acceleration: on
2D Video Acceleration: off
Teleporter Enabled: off
Teleporter Port: 0
Teleporter Address:
Teleporter Password:
Tracing Enabled: off
Allow Tracing to Access VM: off
Tracing Configuration:
Autostart Enabled: off
Autostart Delay: 0
Default Frontend:
Storage Controller Name (0):            IDE
Storage Controller Type (0):            PIIX4
Storage Controller Instance Number (0): 0
Storage Controller Max Port Count (0):  2
Storage Controller Port Count (0):      2
Storage Controller Bootable (0):        on
IDE (0, 0): o:\VirtualBoxDisks\demo_1\demo_export-disk1.vmdk (UUID: ee418695-52a7-45ee-a8fe-c1ba5d9568f7)
IDE (1, 0): Empty
NIC 1:           MAC: 080027CB8540, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 10000 Mbps
, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
NIC 1 Settings:  MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64)
NIC 2:           disabled
NIC 3:           disabled
NIC 4:           disabled
NIC 5:           disabled
NIC 6:           disabled
NIC 7:           disabled
NIC 8:           disabled
Pointing Device: PS/2 Mouse
Keyboard Device: PS/2 Keyboard
UART 1:          disabled
UART 2:          disabled
UART 3:          disabled
UART 4:          disabled
LPT 1:           disabled
LPT 2:           disabled
Audio:           enabled (Driver: DSOUND, Controller: AC97, Codec: STAC9700)
Clipboard Mode:  Bidirectional
Drag and drop Mode: disabled
VRDE:            disabled
USB:             enabled
EHCI:            enabled
XHCI:            disabled

USB Device Filters:
<none>

Bandwidth groups:  <none>

Shared folders:
Name: 'distros', Host path: 'O:\DemoBuilding\Distros' (machine mapping), writable

Video capturing:    not active
Capture screens:    0
Capture file:       o:\VirtualBoxDisks\demo2\demo2.webm
Capture dimensions: 1024x768
Capture rate:       512 kbps
Capture FPS:        25

Guest:

Configured memory balloon size:      0 MB

Let’s boot the machine, make sure that it works, and shut it down again:

@rem start the vm, inspect and shut down
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% startvm "demo2" --type gui

Shrink and clone the source disk

Create a blank, 40GB Virtual Disk to use as target

We need a target disk to which to “clone” the resized source disk partition. Let’s create one.

@rem Create a virtual disk of the right size - 40GB - as target for data move
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
set diskFile=o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk
%VBM% createmedium disk --filename %diskFile% --size 40000 --format VMDK --variant Standard

I see:

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Medium created. UUID: 6bf53b79-630d-41c7-8c98-cf54313d5d7f

Attach the new blank disk to the new VM

Let’s attach the new blank disk to the new VM. This will give us access to both the source and the target disks – source to shrink and target to copy the shrunk partition to.

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
set diskFile=o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk
%VBM% storageattach "demo2" --storagectl "IDE" --port 0 --device 1 --type hdd --medium hdd --medium %diskFile%

Let’s see what this did:

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% showvminfo "demo2" | find "IDE"
Storage Controller Name (0):            IDE
IDE (0, 0): o:\VirtualBoxDisks\demo_1\demo_export-disk1.vmdk (UUID: ee418695-52a7-45ee-a8fe-c1ba5d9568f7)
IDE (0, 1): o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk (UUID: 6bf53b79-630d-41c7-8c98-cf54313d5d7f)
IDE (1, 0): Empty

Boot from GParted Live CD

We need to boot this VM from GParted Live CD. This will give us access to the GParted tools, to the virtual disk which to shrink and to the target disk to which to copy the source partition.

@rem attach GParted ISO
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% storageattach "demo2" --storagectl "IDE" --port 1 --device 0 --type dvddrive --medium O:\DemoBuilding\Distros\gparted-live-0.27.0-1-i686.iso

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% showvminfo "demo2" | find "IDE"
Storage Controller Name (0):            IDE
IDE (0, 0): o:\VirtualBoxDisks\demo_1\demo_export-disk1.vmdk (UUID: ee418695-52a7-45ee-a8fe-c1ba5d9568f7)
IDE (0, 1): o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk (UUID: 6bf53b79-630d-41c7-8c98-cf54313d5d7f)
IDE (1, 0): O:\DemoBuilding\Distros\gparted-live-0.27.0-1-i686.iso (UUID: 7aeea2b7-f91e-43a3-8104-12b23dc4a0c0)

Boot from the GParted ISO

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% startvm "demo2"

Press enter to choose GPated Live

Choose OK to “Don’t touch keymap”.

Choose 33 (US English) for Language and choose 0 to continue to start X to use GParted automatically

GParted UI will appear. Proceed to the next section.

Shrink the source disk file system partition to 30GB

Make sure that the device being operated on is /dev/sda (top right corner of the GParted UI.

Click on the line describing device /dev/sda2 to select it, then click on the Resize/Move button.

Enter 30000 as New Size in MiB, press Tab to advance to the next field and click Resize/Move button.

Click Apply and then Apply again to confirm and to start the process.

Review the feedback and click Close (assuming this worked, which it should)

The source file system partition has be resized, leaving a considerable amount of disk unallocated. Follow next sections to clone the partitions to the new disk.

Partition the target disk

In this section we will partition the target disk, which has not yet been partitioned, so that it has the same number, type and layout of partitions as the source disk.

Pull down the devices drop down, top right corner, and choose the /dev/sdb device – the target disk.

Choose Device–>Create Partition Table …

Choose MSDOS and click Apply

Copy source disk’s swap partition to the target disk

In this section we will copy the swap partition from the source disk, /dev/sda, to the target disk, /dev/sdb, which has a large amount of unallocated space.

Pull down the devices drop down, top right corner, and choose the /dev/sda device – the source disk.

Click the line with /dev/sda1 to select the swap partition and click Copy.

 

Pull down the devices drop down, top right corner, and choose the /dev/sdb device – the target disk, then click Paste.

Leave the size and other aspects of the partition as they are and click the Paste button in the dialogue box.

Click the Apply button in the top button bar to execute the copy, and click Apply again.

Once the copy is completed and you inspected feedback information click the Close button to close the dialogue box

Copy source disk’s file system partition to the target disk

In this section we will copy file system partition from the source disk, /dev/sda, to the target disk, /dev/sdb, which has a large amount of unallocated space.

Pull down the devices drop down, top right corner, and choose the /dev/sda device – the source disk.

Click the line with /dev/sda2 to select the file system partition and click Copy.

Pull down the devices drop down, top right corner, and choose the /dev/sdb device – the target disk, then click Paste.

Adjust the size of the target partition using the slider until the Free space following is 0, then click the Paste button in the dialogue box

Click the Apply button in the top button bar to execute the action. This will take some time, which will vary with the size of the disk.

Once the copy is completed and you inspected feedback information click the Close button to close the dialogue box

Quit GParted.

Reboot with the CentOS Install disk in the DVD drive to have access to system rescue facilities

Double click the Close button, top left, on the desktop to eject the GParted ISO and shut down the image.

Detach the source drive.

set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
set diskFile=o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk
%VBM% storageattach "demo2" --storagectl "IDE" --port 0 --device 0 --type hdd --medium none

Attach CentOS Install ISO

@rem attach CentOS install ISO
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% storageattach "demo2" --storagectl "IDE" --port 1 --device 0 --type dvddrive --medium O:\DemoBuilding\Distros\CentOS-6.8-x86_64-bin-DVD1.iso
%VBM% showvminfo "demo2" | find "IDE"
Storage Controller Name (0):            IDE
IDE (0, 1): o:\VirtualBoxDisks\demo2\demo2-disk1.vmdk (UUID: 6bf53b79-630d-41c7-8c98-cf54313d5d7f)
IDE (1, 0): O:\DemoBuilding\Distros\CentOS-6.8-x86_64-bin-DVD1.iso (UUID: c5ace9b9-edb3-4796-82c6-374c78991750)

Boot the image

@rem boot
%VBM% startvm "demo2"

Follow next section to fix the grub boot loader

Fix the Grub Bootloader

Choose the Rescue Installed System option and press enter

Choose Language English and OK

Choose Keyboard Type us and OK

Choose Setup Networking NO

Choose Rescue Continue

Choose OK

Choose OK

Choose Start Shell

Execute the following commands

chroot /mnt/sysimage
/sbin/grub-install /dev/sda
exit
exit

Choose Reboot to get back to the install menu

In Virtual Box menu bar click the close button and choose Power off the machine to stop the VM

Reboot with just the target disk attached

Detach the installation ISO and boot the image

@rem attach CentOS install ISO
set VBM="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
%VBM% storageattach "demo2" --storagectl "IDE" --port 1 --device 0 --type dvddrive --medium none

Boot the image

@rem boot
%VBM% startvm "demo2"

Verify partitioning and partition sizes by executing in a terminal window

lsblk

I see:

NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0 39.1G  0 disk
??sda1   8:1    0    8G  0 part [SWAP]
??sda2   8:2    0 31.1G  0 part /

And

df -h

I see:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        31G  5.8G   24G  20% /
tmpfs           1.9G   76K  1.9G   1% /dev/shm

Shut down the VM – it is ready to use

Nov 27

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

From time to time I may need another user account, configured with the same tools and settings as the demo user which was used in the earlier articles and will continue to be used in the subsequent articles.

In this post I show how a new user can be created and configured using the scripts which were already developed and which are available for use.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.
  2. The user “demo” has sudo access without a password. If this is not the case use the command “su -” and provide the password instead of saying “sudo -i” in the set of commands below

The instructions should work in other RedHat 6-like OS’ and OS versions.

Discussion

Let’s assume that we need another user’s environment configured the same way as the demo user’s environment. We were creating configuration scripts in the following articles:

  1. CentOS 6.8 – Script Adding Top Panel Applets – GEyes, ShowDesktop and Gnome Monitor
  2. CentOS 6.8 – Script adding a new gnome-terminal profile
  3. CentOS 6.8 – Create desktop branding scripts and brand desktop

Since the scripts are already available we will, in this article, create a different user, log in as that user, and execute the scripts to set up the environment.

Add user

Assuming that we are logged in as the demo user, which we will be if the article series was followed in the order in which it was published, we have sudo access.

NewUsername=ademo2
sudo useradd -c "${NewUsername} User" -m ${NewUsername}

sudo passwd ${NewUsername} <<'EOF'
welcome1
welcome1
EOF

sudo usermod -G vboxsf ${NewUsername}

Verify that the account was created

sudo -i -u ademo2 ls -al

su ademo2
Password: welcome1

cd
ls -al

exit

Use gdmflexiserver to switch to user ademo2 by running the following command

gdmflexiserver

The Greeter is displayed

041_greeter

Click “Other…”, then enter ademo2 as username and welcome1 as password.

Notice that the login desktop does not have the top panel applets to which we got used to by now when using the demo login into which we are automatically logged in at boot.

Disable Screen Saver and inactivity timer

After a while of inactivity a screen saver will be run. Let’s disable this feature. Right-click on the desktop and choose “Open in Terminal”, then execute the command scripts:

/bin/bash -v /media/sf_distros/scripts/002_disable_screen_saver_and_delays.sh

Configure top panel applets and nautilus file browser

Assuming that we are logged in as user ademo2, let’s add the top panel applets and configure nautilus file browser. Right-click on the desktop and choose “Open in Terminal…”, then execute the command scripts:

# add applets to top panel - you will get "Operation not permitted" at the end but the script will complete what it needs to do
/bin/bash -v /media/sf_distros/scripts/005_add_applets_to_top_panel.sh

# Add standard launchers to top panel - first "fix" the script which has the demo user embedded
sed -i 's|/demo/|/${USER}/|' /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh
/bin/bash -v /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh

/bin/bash -v /media/sf_distros/scripts/008_configure_nautilus_file_browser.sh

Configure gnome-terminal profiles

Assuming that this user account will be used to do the same kinds of things that the dmeo use will, let’s add the gnome-terminal profiles that we added for the demo user

/bin/bash -v /media/sf_distros/scripts/010_make_profile_very_visible.sh
/bin/bash -v /media/sf_distros/scripts/011_make_profile_console_scrolling.sh

Brand the desktop

Let’s brand the desktop so that we know what is there. This, as you will undoubtedly realise, is done on per-user basis, and perhaps needs to be reconsidered. If additional software is installed by a different user, for example the root user, neither the demo user nor the ademo2 user will have this reflected in their branded desktop. Still, this is probably better than nothing and as long as the administrator updates the branding files and runs the branding script at appropriate times things should go well enough.

# copy desktop branding script to the local directory for execution
# only needs to be done the first time
cp -v /media/sf_distros/scripts/013_source_desktop_branding_script.sh ${HOME}/brand_desktop.sh

# create a rarely changing content
cat <<-'EODECK' > ${HOME}/copyright_and_credits.txt
Copyright © 2016, Michael Czapski
EODECK

# create "current state" content - only needs to be done the first time branding is done
oldVer="v0.0.0"
newVer="v1.1.0"
touch ${HOME}/branding_installed_software_${oldVer}.txt
cp ${HOME}/branding_installed_software_${oldVer}.txt ${HOME}/branding_installed_software_${newVer}.txt

idLabel="Installed and Configured CentOS 6.8"

# append to "current state" content
cat <<-EODECK >> ${HOME}/branding_installed_software_${newVer}.txt
${newVer}, $(date +%Y-%m-%d\ %H:%M)
${idLabel}
EODECK

# brand the desktop
annotationFile=${HOME}/branding_installed_software_${newVer}.txt
creditsFile=${HOME}/copyright_and_credits.txt
buildFile=${HOME}/build_date.txt

${HOME}/brand_desktop.sh "${idLabel}" "${annotationFile}" "${creditsFile}" "${newVer}"

Explore, then log out from ademo2 user and return to demo user

Nov 26

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

As I work with the various demonstration images I find myself taking longish breaks between bouts of activity so I like to have a clear indication, right on the desktop, of what state the image is in. What software was installed, what tis the name of the checkpoint I reached so that I can look up the specific section in the installation document I build at the same time, and so that I can resume work where I left off.

In this post I walk through the method of “branding” the desktop with text which tells me that what is installed, what the checkpoint has been reached, what the host name is and what user is logged in. I will subsequently use this script to brand the desktop each time something significant is done to the image.

The image blow shows the desktop branded using the method described in this article.

040_branded_desktop

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.

The instructions should work in other RedHat 6-like OS’ and OS versions and on platforms that use gnome-2 desktop.

Discussion

The branding method relies on the ability to change desktop background using gconftool-2 by providing a location of the image which to use, and on the fact that ImageMagc can be used to programmatically manipulate images by adding text and other graphical artefacts to existing images.

This capability is used to mark up an existing desktop image with text that reflects the username, host name, label designating the state the image is in and a list of software which was installed up to the point at which desktop was branded.

Update ImageMagic Security Profile

As shipped in CentOS 6.8 and Oracle Linux 6U8 at least, ImageMagic, which I use to manipulate desktop image I will use, has security restrictions which prevent it being use the way it needs to be used to accomplish what needs to be accomplished in this post. To allow the manipulation to be done one must replace the ImageMagic security policy file. We will develop a script, to be added to the bilk initial setup script set, in the next section.

Let’s create a script which will update the ImageMagic security profile so that we can watermark the desktop image with text we want to see on the desktop.

cat <<-'EODECK' > /media/sf_distros/scripts/012_update_imagemagic_security_profile.sh

# Save ImageMagic policy file
if [ ! -f /etc/ImageMagick/policy.xml_orig ]; then
    sudo cp -v /etc/ImageMagick/policy.xml /etc/ImageMagick/policy.xml_orig
fi

# Create replacement policy file
cat <<-'EOF' | sudo tee /etc/ImageMagick/policy.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policymap [
<!ELEMENT policymap (policy)+>
<!ELEMENT policy (#PCDATA)>
<!ATTLIST policy domain (delegate|coder|filter|path|resource) #IMPLIED>
<!ATTLIST policy name CDATA #IMPLIED>
<!ATTLIST policy rights CDATA #IMPLIED>
<!ATTLIST policy pattern CDATA #IMPLIED>
<!ATTLIST policy value CDATA #IMPLIED>
]>
<!--
  Configure ImageMagick policies.

 Domains include system, delegate, coder, filter, path, or resource.
 Rights include none, read, write, and execute.  Use | to combine them,
  for example: "read | write" to permit read from, or write to, a path.
  Use a glob expression as a pattern.
  Suppose we do not want users to process MPEG video images:
    <policy domain="delegate" rights="none" pattern="mpeg:decode" />
  Here we do not want users reading images from HTTP:
    <policy domain="coder" rights="read | write" pattern="HTTP" />
  Lets prevent users from executing any image filters:
    <policy domain="filter" rights="none" pattern="*" />
  The /repository file system is restricted to read only.  We use a glob
  expression to match all paths that start with /repository:
    <policy domain="path" rights="read" pattern="/repository/*" />
  Let's prevent possible exploits by removing the right to use indirect reads.
    <policy domain="path" rights="none" pattern="@*" />
  Any large image is cached to disk rather than memory:
    <policy domain="resource" name="area" value="1gb"/>
  Note, resource policies are maximums for each instance of ImageMagick (e.g.
  policy memory limit 1GB, -limit 2GB exceeds policy maximum so memory limit
  is 1GB).
-->
<policymap>
  <!-- <policy domain="system" name="precision" value="6"/> -->
  <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> -->
  <!-- <policy domain="resource" name="memory" value="2GiB"/> -->
  <!-- <policy domain="resource" name="map" value="4GiB"/> -->
  <!-- <policy domain="resource" name="area" value="1gb"/> -->
  <!-- <policy domain="resource" name="disk" value="16eb"/> -->
  <!-- <policy domain="resource" name="file" value="768"/> -->
  <!-- <policy domain="resource" name="thread" value="4"/> -->
  <!-- <policy domain="resource" name="throttle" value="0"/> -->
  <!-- <policy domain="resource" name="time" value="3600"/> -->
  <policy domain="coder" rights="read | write" pattern="EPHEMERAL" />
  <policy domain="coder" rights="read | write" pattern="HTTPS" />
  <policy domain="coder" rights="read | write" pattern="HTTP" />
  <policy domain="coder" rights="read | write" pattern="URL" />
  <policy domain="coder" rights="read | write" pattern="FTP" />
  <policy domain="coder" rights="read | write" pattern="MVG" />
  <policy domain="coder" rights="read | write" pattern="MSL" />
  <policy domain="coder" rights="read | write" pattern="TEXT" />
  <policy domain="coder" rights="read | write" pattern="LABEL" />
  <policy domain="coder" rights="read | write" pattern="TXT" />
<!--  <policy domain="path" rights="none" pattern="@*" /> -->
</policymap>
EOF
EODECK
chmod ug+x /media/sf_distros/scripts/012_update_imagemagic_security_profile.sh

Execute the script to update the policy file

/bin/bash -v /media/sf_distros/scripts/012_update_imagemagic_security_profile.sh

See the differences

diff -y --suppress-common-lines /etc/ImageMagick/policy.xml /etc/ImageMagick/policy.xml_orig

Create Desktop Branding script

Create the branding script with 4 arguments

cat <<-'EODECK' > /media/sf_distros/scripts/013_source_desktop_branding_script.sh
#!/bin/bash
# check that each individual argument exists
: ${1?"Usage: $0 " '${idLabel} ${annotationFile} ${creditsFile} ${newVer} - provide content for the idLabel - exiting ...'}
: ${2?"Usage: $0 " '${idLabel} ${annotationFile} ${creditsFile} ${newVer} - provide path to annotationFile - exiting ...'}
: ${3?"Usage: $0 " '${idLabel} ${annotationFile} ${creditsFile} ${newVer} - provide path to creditsFile - exiting ...'}
: ${4?"Usage: $0 " '${idLabel} ${annotationFile} ${creditsFile} ${newVer} - provide version number like 'v1.2.3' - exiting ...'}

idLabel=${1}
annotationFile=${2}
creditsFile=${3}
newVer=${4}

# "build date" is a date/tim stamp reflecting when the script was run
cat <<-EOF > ${HOME}/build_date.txt
Build: ${newVer}, $(date +%d\ %b\ %Y\ %H:%M)
EOF
buildFile=${HOME}/build_date.txt

# ImageMagic command uses the default.png background - this can be readily changes
# Username and Host name are written near the top right (northeast) in 42pt
# and near the bottom left (southwest) in 32pt
# content of the annotation file, credits file and build file are written in the appropriate
# places in the image - see pictire for where this is
#
mkdir -p ~/imgman
cd ~/imgman
bgfile=$(hostname -s)_${USER}.jpg
myhost=$(hostname)
convert /usr/share/backgrounds/default.png \
-gravity northeast -fill white -pointsize 42 \
-annotate +20+60 "${idLabel}\n${USER}\n${myhost}" \
-gravity southwest -fill white -pointsize 32 \
-annotate +20+40 "${myhost}\n${USER}\n${idLabel}" \
-gravity northwest -fill white -pointsize 18 \
-annotate +300+120 @${annotationFile} \
-gravity southwest -fill white -pointsize 14 \
-annotate +700+120 "$( cat ${creditsFile})" \
-gravity southwest -fill white -pointsize 14 \
-annotate +700+100 "$( cat ${buildFile})" \
${bgfile}

# replace the current desktop background with the modified desktop background
gconftool-2 -s -t string /desktop/gnome/background/picture_filename "${HOME}/imgman/${bgfile}"
EODECK
chmod ug+x /media/sf_distros/scripts/013_source_desktop_branding_script.sh

Copy desktop branding script to the local directory for use

cp -v /media/sf_distros/scripts/013_source_desktop_branding_script.sh ${HOME}/brand_desktop.sh

Brand the desktop

Create branding file with the content that rarely changes – it will appear at the centre near the bottom of the desktop

cat <<-'EODECK' > ${HOME}/copyright_and_credits.txt
Copyright © 2016, Michael Czapski
EODECK

It is expected that the software list file, which in my case contains the list of software I installed and configured, will grow between the times the desktop gets branded. To keep the list up to date one will copy the most recent version of the branding file with a new version and append text to it to provide information on what changed since.

Append to software list file – the first time around the software list file will not exist

oldVer="v0.0.0"
newVer="v1.1.0"
touch ${HOME}/branding_installed_software_${oldVer}.txt
cp ${HOME}/branding_installed_software_${oldVer}.txt ${HOME}/branding_installed_software_${newVer}.txt

Label is the text that identifies the current iteration of the image and in my case correlates with the checkpoint names in the installation document used to build the image and possibly with the snapshot names in VirtualBox .

idLabel="Installed and Configured CentOS 6.8"

The branding file incorporates the version, date/time stamp and the label

cat <<-EODECK >> ${HOME}/branding_installed_software_${newVer}.txt
${newVer}, $(date +%Y-%m-%d\ %H:%M)
${idLabel}
EODECK

Execute the script to brand the desktop

annotationFile=${HOME}/branding_installed_software_${newVer}.txt
creditsFile=${HOME}/copyright_and_credits.txt
buildFile=${HOME}/build_date.txt

${HOME}/brand_desktop.sh "${idLabel}" "${annotationFile}" "${creditsFile}" "${newVer}"

Add to initial bulk configuration script

It is expected that the image being configured a bit at a time in this series of articles will be created more than once for different purposes. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Copy the global desktop branding script to the local directory for execution

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# update ImageMagic security policy file
/bin/bash -v /media/sf_distros/scripts/012_update_imagemagic_security_profile.sh

# copy desktop branding script to the local directory for execution
cp -v /media/sf_distros/scripts/013_source_desktop_branding_script.sh ${HOME}/brand_desktop.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Nov 20

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

As I work with the various demonstration images I find myself using gnome-terminal profiles configured to display server logs, scripting interactions and other kinds of stuff using different font sizes, terminal backgrounds and application exit behaviours. I used to configure these manually in each image, then dumping configured profiles into a xml file and loading them into a new image. The gnome-terminal dumps are quite large so this is somewhat cumbersome.

In this post I walk through the method of script-driven addition of gnome terminal profiles and gconftool-2-based configuration so that all of this can be scripted and can avoid the need to do it manually.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.

The instructions should work in other RedHat 6-like OS’ and OS versions and on platforms that use gnome-2 desktop.

Discussion

A gnome-terminal profile can be created manually. Just start a gnome-terminal, pull down the Edit menu, choose Profiles and Add new profile. Creating a new profile programmatically is harder.

The following commands will find out what is the “last” profile and will work out what the internal name of the new profile needs to be, then will clone the Default profile and use it to create a new profile, with the new internal and visible names, ready for gconftool-2 configuration.

If you execute these commands you will create a profile.

In the next section you will create scripts which combine all of these commands so that a profile can be created using a single script.

By exporting and manipulating the gnome-terminal global profile list we will determine the name of the “last” profile. This name will either be “Default”, if there is only one, the default profile, or a name of the form “ProfileX”, where X will be 0, 1, 2, …, depending on the number of profiles, in addition to the “Default” profiles, which are configured.

The profile list will look like [Default], or [Default,Profile0], i.e. there will be square brackets surrounding the comma-separated list of names. The sed command will strip the square brackets so that we get just the comma-separated list of names.

profiles_list=$(gconftool-2 --get "/apps/gnome-terminal/global/profile_list" | sed "s|\[||;s|\]||;")
echo "1 Profiles List: " ${profiles_list}

Let’s take the list of profile names, “Default” or “Default,Profile0,Provile1”, etc.. and remove all elements from the list up to and including the last comma. This will leave either the last profile name of the form “ProfileX” or the literal “Default”

last_profile=$(echo "${profiles_list}" | sed "s/^.*,//" | sed 's/Profile//')
echo "Last Profile Name/Number: " ${last_profile}

If the last_profile is the literal “Default” then the “next” internal profile name will be “Profile0” otherwise it will be Profile(X + 1) -> is 2 then Profile3, etc.

Let’s set the “ProfileX” X number to 0 if only default is there or whatever the last is plus 1

if [ ${last_profile} == "Default" ]; then
    next_profile_number=0;
    echo "1 New Profile Number: " ${next_profile_number}
else
    next_profile_number=$(( ${last_profile} + 1 ));
    echo "2 New Profile Number: " ${next_profile_number}
fi
echo "New Profile Number: " ${next_profile_number}

We need to tell gnome that the list of profile names is different. If it was “Default,Profile0” then with the new profile it needs to be “Default,Profile0,Profile1”

Let’s construct profiles list with extra profile “number”

profiles_list=$(echo "[${profiles_list},Profile${next_profile_number}]")
echo "1 Profiles List: " ${profiles_list}

By now we established the new internal profile name – Profile0 or Profile1 or …

Let’s set the new visible profile name as an environment variable for ease of use later

profileName=MyNewProfile

Let’s get a dump of the default profile. We will use it as a template for the new profile

gconftool-2 --dump "/apps/gnome-terminal/profiles/Default" > /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

Let’s change global name to the new internal profile name in the Default profile dump

sed -i “s|Default|Profile${next_profile_number}|g” /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

Let’s load the new profile – it will not be useable until the next step is executed

gconftool-2 --load /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

Let’s tell gnome-terminal that is has another profile by updating the profile_list property

gconftool-2 --set --type list --list-type string "/apps/gnome-terminal/global/profile_list" "${profiles_list}"

Let’s change the visible_name property to the “friendly” name we want to see in the Profiles dropdown

gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/visible_name "${profileName}"

Let’s set other properties to suit

gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/use_system_font "false"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/use_theme_colors "false"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/login_shell "true"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/default_show_menubar "false"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/scrollback_unlimited "true"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/exit_action "hold"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/font "Monospace 14"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/background_color "#FFFFFFFFDDDD"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/foreground_color "#0000FFFF0000"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/scrollbar_position "hidden"

Let’s create a terminal using the profile we just created

gnome-terminal --geometry=80x24+0+0 --profile=${profileName} title "${profileName}" --zoom 0.8 -e "/bin/sh"

The steps above helped us create and configure a new gnome-terminal profile and create a terminal which is using that profile.

Design the “create new gnome-terminal profile” script

cat <<-'EODECK' > /media/sf_distros/scripts/create_new_gnome-terminal_profile.sh
#!/bin/bash
# The following script will find out what is the "last" profile and will work out
# what the internal name of the new profile needs to be, then will clone the Default profile
# and use it to create a new profile, with the new internal and visible names,
# ready for gconftool-2 configuration.

# Let's set the new visible profile name as an environment variable
# for ease of use later

profileName=${1?"Usage: $0 profileName # please provide value for the visible_name profile property - make sure that it is a valid string identifier, i.e consisting of letters and digits only"}

# By exporting and manipulating the gnome-terminal global profile list we will determine
# the name of the "last" profile. This name will either be "Default", if there is only one,
# the default profile, or a name of the form "ProfileX", where X will be 0, 1, 2, …,
# depending on the number of profiles, in addition to the "Default" profiles,
# which are configured.

profiles_list=$(gconftool-2 --get "/apps/gnome-terminal/global/profile_list" | sed "s|\[||;s|\]||;")
echo "1 Profiles List: " ${profiles_list}

# Let's take the list of profile names, "Default" or "Default,Profile0,Provile1", etc..
# and remove all elements from the list up to and including the last comma.
# This will leave either the last profile name of the form "ProfileX" or the literal "Default"

last_profile=$(echo "${profiles_list}" | sed "s/^.*,//" | sed 's/Profile//')
echo "Last Profile Name/Number: " ${last_profile}

# If the last_profile is the literal "Default" then the "next" internal profile name
# will be "Profile0" otherwise it will be Profile(X + 1) -> is 2 then Profile3, etc.
# Let's set the "ProfileX" X number to 0 if only default is there or whatever the last is
# plus 1

if [ ${last_profile} == "Default" ]; then
    next_profile_number=0;
    echo "1 New Profile Number: " ${next_profile_number}
else
    next_profile_number=$(( ${last_profile} + 1 ));
    echo "2 New Profile Number: " ${next_profile_number}
fi
echo "New Profile Number: " ${next_profile_number}

# We need to tell gnome that the list of profile names is different.
# If it was "Default,Profile0" then with the new profile
# it needs to be "Default,Profile0,Profile1"
# Let's construct profiles list with extra profile "number"

profiles_list=$(echo "[${profiles_list},Profile${next_profile_number}]")
echo "1 Profiles List: " ${profiles_list}

# By now we established the new internal profile name - Profile0 or Profile1 or ...

# Let's get a dump of the default profile. We will use it as a template for the new profile

gconftool-2 --dump "/apps/gnome-terminal/profiles/Default" > /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

# Let's change global name to the new internal profile name in the Default profile dump

sed -i "s|Default|Profile${next_profile_number}|g" /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

# Let's load the new profile - it will not be useable until the next step is executed

gconftool-2 --load /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

# Let's tell gnome-terminal that is has another profile by updating the profile_list property

gconftool-2 --set --type list --list-type string "/apps/gnome-terminal/global/profile_list" "${profiles_list}"

# Let's change the visible_name property to the "friendly" name we want to see
# in the Profiles dropdown

gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/visible_name "${profileName}"

EODECK
chmod ug+x /media/sf_distros/scripts/create_new_gnome-terminal_profile.sh

The following script, given the name of the profile, the data type fo the property to change, the name of the property to change and the value to which to change the property will make the change

cat <<-'EODECK' > /media/sf_distros/scripts/set_profile_property.sh
#!/bin/bash

profileName=${1?"Usage: $0 profileName keyName keyType keyValue # please provide value of the visible_name of the profile whose property you want to change"}
keyName=${2?"Usage: $0 profileName keyName keyType keyValue # please provide name of the profile key which you want to change"}
keyType=${3?"Usage: $0 profileName keyName keyType keyValue # please provide data type of the profile key which you want to change - boolean, string are supported - lists are not"}
keyValue=${4?"Usage: $0 profileName keyName keyType keyValue # please provide value of the profile key which you want to change"}

profileNum=$(gconftool-2 --search-key visible_name | grep ${profileName} | tail -n 1 | sed 's|^.*/Profile||;s|/.*$||')
echo "ProfileNum: " ${profileNum}

gconftool-2 --set --type ${keyType} /apps/gnome-terminal/profiles/Profile${profileNum}/${keyName} "${keyValue}"
EODECK
chmod ug+x /media/sf_distros/scripts/set_profile_property.sh

Create scripts for new profiles very_visble and console_scrolling

The very_visible profile will have larger font (Monospace, 14) and a green background, to distinguish the very_visible terminal from a “regular” gnome-terminal.

cat <<-'EODECK' > /media/sf_distros/scripts/010_make_profile_very_visible.sh
#!/bin/bash
/media/sf_distros/scripts/create_new_gnome-terminal_profile.sh very_visible

/media/sf_distros/scripts/set_profile_property.sh very_visible use_system_font boolean false
/media/sf_distros/scripts/set_profile_property.sh very_visible use_theme_colors boolean false
/media/sf_distros/scripts/set_profile_property.sh very_visible login_shell boolean true
/media/sf_distros/scripts/set_profile_property.sh very_visible default_show_menubar boolean false
/media/sf_distros/scripts/set_profile_property.sh very_visible scrollback_unlimited boolean true
/media/sf_distros/scripts/set_profile_property.sh very_visible exit_action string hold
/media/sf_distros/scripts/set_profile_property.sh very_visible font string "Monospace 14"
/media/sf_distros/scripts/set_profile_property.sh very_visible background_color string "#FFFFFFFFDDDD"
/media/sf_distros/scripts/set_profile_property.sh very_visible foreground_color string "#000000000000"
/media/sf_distros/scripts/set_profile_property.sh very_visible scrollbar_position string hidden
EODECK
chmod ug+x /media/sf_distros/scripts/010_make_profile_very_visible.sh

 

The console_scrolling profile will have larger font (Monospace, 9) and a black background, to distinguish the console_scrolling terminal from a “regular” gnome-terminal.

cat <<-'EODECK' > /media/sf_distros/scripts/011_make_profile_console_scrolling.sh
#!/bin/bash
/media/sf_distros/scripts/create_new_gnome-terminal_profile.sh console_scrolling

/media/sf_distros/scripts/set_profile_property.sh console_scrolling use_system_font boolean false
/media/sf_distros/scripts/set_profile_property.sh console_scrolling use_theme_colors boolean false
/media/sf_distros/scripts/set_profile_property.sh console_scrolling login_shell boolean true
/media/sf_distros/scripts/set_profile_property.sh console_scrolling default_show_menubar boolean false
/media/sf_distros/scripts/set_profile_property.sh console_scrolling scrollback_unlimited boolean true
/media/sf_distros/scripts/set_profile_property.sh console_scrolling scroll_on_output boolean true
/media/sf_distros/scripts/set_profile_property.sh console_scrolling exit_action string hold
/media/sf_distros/scripts/set_profile_property.sh console_scrolling font string "Monospace 9"
/media/sf_distros/scripts/set_profile_property.sh console_scrolling background_color string "#000000000000"
/media/sf_distros/scripts/set_profile_property.sh console_scrolling foreground_color string "#FFFFFFFFFFFF"
/media/sf_distros/scripts/set_profile_property.sh console_scrolling scrollbar_position string hidden
EODECK
chmod ug+x /media/sf_distros/scripts/011_make_profile_console_scrolling.sh

Execute commands to create and configure the two profiles

/bin/bash -v /media/sf_distros/scripts/010_make_profile_very_visible.sh
/bin/bash -v /media/sf_distros/scripts/011_make_profile_console_scrolling.sh

Add to initial bulk configuration script

It is expected that the image being configured a bit at a time in this series of articles will be created more than once for different purposes. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Append “create gnome-terminal profiles” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# create very_visible gnome-terminal profile
/bin/bash -v /media/sf_distros/scripts/010_make_profile_very_visible.sh

# create console_scrolling gnome-terminal profile
/bin/bash -v /media/sf_distros/scripts/011_make_profile_console_scrolling.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Nov 05

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

As I work with the various demonstration images I find myself using the same tools, I naturally expect the tools to be ready to hand so I find myself adding the same launchers to the top panel.

In this article I build and execute a script which will add the “Update DHCP address in /etc/hosts at boot” script to the interactive boot level startup sequence so that the ip address is updated at boot to reflect the host ip address assigned to the host by DHCP. As in previous blog articles I also add the new scripts to the “initial configuration” script which is built cumulatively in the various articles in this series.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.
  2. The user “demo” has sudo access without a password. If this is not the case use the command “su -” and provide the password instead of saying “sudo -i” in the set of commands below

The instructions should work in other RedHat 6-like OS’ and OS versions.

Discussion

In the demonstration image as configured so far, there is no reference to the demo.demodomain.org in the /etc/hosts file.

We could manually update the /etc/hosts and point the demo.demodomain.org to 120.0.0.1, the loopback address. If it matters that the demo.demodomain.org points to an actual IP address of the NAT interface which a DHCP server assigns, and may change at different times or on different networks, we are better off creating a script to set /etc/hosts at boot so that the correct IP address is embedded. Everything that wants to translate the host name to the IP address uses /etc/hosts.

The /etc/hosts in the image, as at now, looks like this:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

Let’s explore how this hosts file can be “fixed” to configure the “real” IP address of the host at boot time.

Before making changes to the /etc/hosts file lets save it so we can restore it if things go wrong.

sudo cp /etc/hosts /etc/hosts_as_installed

Let’s append the 127.0.0.1 address to /etc/hosts – it will be replaced by the script we are going to create shortly.

cat <<-'EOF' | sudo tee --append /etc/hosts
127.0.0.1   demo.demodomain.org
EOF

Add boot-time script to insert the current DHCP host IP and associate it with the host name

cat <<-'EOF' | sudo tee /etc/init.d/ofixhostip
#!/bin/bash
ipaddr=$(/sbin/ifconfig eth0| grep 'inet addr' | cut -d: -f2 | awk '{print $1}')
hn=$(hostname -s)
hnd=$(hostname)
sed -i '$s/.*/'$ipaddr'  '$hnd'   '$hn'/' /etc/hosts
EOF
sudo chmod ug+x /etc/init.d/ofixhostip

Add to interactive boot level (5) sequence

sudo /bin/sh -c "cd /etc/rc5.d; ln -s ../init.d/ofixhostip S10ofixhostip"

Reboot

sudo reboot

Verify IP address in /etc/hosts

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.2.15  demo.demodomain.org   demo

Restore after changes to the /etc/hosts file so that we can test the script we will be developing

sudo cp -v /etc/hosts_as_installed /etc/hosts

Implementation

Now that we understand what needs to be done, and know how to do it, let’s create a script that will automate this part of image configuration for the next time we are creating a new image that needs this functionality.

Create the configuration script

mkdir -p /media/sf_distros/scripts
cat <<-'EODECK' > /media/sf_distros/scripts/009_update_dhcp_address_at_boot.sh
#!/bin/bash
# add replacement placeholder
cat <<-'EOF' | sudo tee --append /etc/hosts
127.0.0.1   demo.demodomain.org
EOF

# Add boot-time script to insert the current DHCP host IP and associate it with the host name
cat <<-'EOF' | sudo tee /etc/init.d/ofixhostip
#!/bin/bash
ipaddr=$(/sbin/ifconfig eth0| grep 'inet addr' | cut -d: -f2 | awk '{print $1}')
hn=$(hostname -s)
hnd=$(hostname)
sed -i '$s/.*/'$ipaddr'  '$hnd'   '$hn'/' /etc/hosts
EOF
sudo chmod ug+x /etc/init.d/ofixhostip

# Add to interactive boot level (5) sequence
sudo /bin/sh -c "cd /etc/rc5.d; ln -f -s ../init.d/ofixhostip S10ofixhostip"

EODECK
chmod ug+x /media/sf_distros/scripts/009_update_dhcp_address_at_boot.sh

Execute the script

/bin/bash -v /media/sf_distros/scripts/009_update_dhcp_address_at_boot.sh

Reboot

sudo reboot

Verify IP address in /etc/hosts

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.2.15  demo.demodomain.org   demo

It is expected that the image being configured a bit at a time in this series of articles will be created more than once for different purposes. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Append “Update DHCP address in /etc/hosts at boot” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# Update DHCP address in /etc/hosts at boot
/bin/bash -v /media/sf_distros/scripts/009_update_dhcp_address_at_boot.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Oct 29

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.
  2. The user “demo” has sudo access without a password. If this is not the case use the command “su -” and provide the password instead of saying “sudo -i” in the set of commands below

The instructions should work in other RedHat 6-like OS’ and OS versions.

Download alacarte

The alacarte application is a UI for managing the gnome 2 menus. CentOS 6.8, as installed following instructions in the second article in this series, does not include alacarte, so it is necessary to install it. We will do it in two steps – first we will download it and then we will install it form a shared directory. This way we will download it the first time but will subsequently be able to install it on as many images as we care to create without the need to go to the Internet each time.

mkdir -p /media/sf_distros/rpms

sudo yum install -y --downloadonly --downloaddir=/media/sf_distros/rpms alacarte
ls /media/sf_distros/rpms/alacarte*
/media/sf_distros/rpms/alacarte-0.12.4-1.el6.noarch.rpm

Download gconf-editor

The gconf-editor application is a UI for exploring and modifying gnome configuration. CentOS 6.8, as installed following instructions in the second article in this series, does not include gconf-editor, so it is necessary to install it. We will do it in two steps – first we will download it and then we will install it form a shared directory. This way we will download it the first time but will subsequently be able to install it on as many images as we care to create without the need to go to the Internet each time.

mkdir -p /media/sf_distros/rpms
sudo yum install -y --downloadonly --downloaddir=/media/sf_distros/rpms gconf-editor
ls /media/sf_distros/rpms/gconf-editor*
/media/sf_distros/rpms/gconf-editor-2.28.0-3.el6.x86_64.rpm

Create localinstall rpm script

Let’s create a script to install a rpm from the shared directory.

cat <<-'EODECK' > /media/sf_distros/scripts/006_install_local_rpm.sh
#!/bin/bash
rpmNamePattern=${1?"Usage: $0 rpmName # please provide rpm name"}
rpmName=$(ls -c1 /media/sf_distros/rpms/${rpmNamePattern}* ) 2>/dev/null
if [ $? -ne 0 ]; then
    echo "ERROR: No files satisfying the pattern /media/sf_distros/rpms/${rpmNamePattern}*  - can't install ${rpmNamePattern}";
else
    if [ "$(yum list ${rpmNamePattern} 2>/dev/null | grep @/${rpmNamePattern})" == "" ]; then
        echo "Will install ${rpmName}";
        sudo yum -y localinstall ${rpmName}
    else
        echo "${rpmName} is already installed - skipping installation"
    fi
fi

EODECK
chmod ug+x /media/sf_distros/scripts/006_install_local_rpm.sh

Some references:

http://tldp.org/LDP/abs/html/parameter-substitution.html#USAGEMESSAGE

http://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html

 

Install alacarte and gconf-editor

Install alacarte

/bin/bash -v /media/sf_distros/scripts/006_install_local_rpm.sh alacarte

Install gconf-editor

/bin/bash -v /media/sf_distros/scripts/006_install_local_rpm.sh gconf-editor

Add Launchers to Top Panel

The launchers are gnome-specific text files which define the various aspects of each launcher, and which can either be added to a panel, as is done in this article, or can be placed on the Desktop, which is done in one or more of the subsequent articles.

See “Integrating existing software with GNOME, Guide for Independent Software Vendors”, https://developer.gnome.org/integration-guide/stable/index.html.en, for specifics of the structure of the *.desktop file.

If you worked through the previous article, your top panel will look like in the following illustration.

038_centos_top_panel_after

The launchers for the top panel will go into a specific directory under the user’s home directory, in my case it will be “~/.gnome2/panel2.d/default/launchers/”.

Let’s create a script which adds Alacarte, Gedit, pre-configured gnome-terminal, Nautilus File Manager and KDE Monitor to the top panel.

Note, in the script below, that while we are creating the *.desktop files each time, we are verifying whether the particular launcher has already been added to the panel and are not adding it if it has. This is because each time the gnome-panel-add command is execute a new launcher is added regardless of whether an identical one is already there.

mkdir -p /media/sf_distros/scripts
cat <<-EODECK > /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh
#!/bin/bash
mkdir -p ${HOME}/.gnome2/panel2.d/default/launchers/
cat <<-EOF > ${HOME}/.gnome2/panel2.d/default/launchers/alacarte.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=alacarte
Name=alacarte
Icon=alacarte
EOF
/usr/bin/gconftool-2 --dump /apps/panel/objects | grep alacarte.desktop 2>/dev/null 1>&2
if [ \$? -eq 0 ]; then
    echo "Launcher for alacarte already in the top panel";
else
    /usr/libexec/gnome-panel-add --panel=top_panel --launcher=${HOME}/.gnome2/panel2.d/default/launchers/alacarte.desktop --position=710
fi

cat <<-EOF > ${HOME}/.gnome2/panel2.d/default/launchers/gedit.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=gedit
Name=gedit
Icon=/usr/share/icons/gnome/scalable/apps/accessories-text-editor.svg
EOF
/usr/bin/gconftool-2 --dump /apps/panel/objects | grep gedit.desktop 2>/dev/null 1>&2
if [ \$? -eq 0 ]; then
    echo "Launcher for gedit already in the top panel";
else
    /usr/libexec/gnome-panel-add --panel=top_panel --launcher=${HOME}/.gnome2/panel2.d/default/launchers/gedit.desktop --position=280
fi

cat <<-EOF > ${HOME}/.gnome2/panel2.d/default/launchers/gnome-terminal.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=gnome-terminal --geometry 100x24+800+350
Name=gnome-terminal
Icon=/usr/share/icons/gnome/scalable/apps/utilities-terminal.svg
EOF
/usr/bin/gconftool-2 --dump /apps/panel/objects | grep gnome-terminal.desktop 2>/dev/null 1>&2
if [ \$? -eq 0 ]; then
    echo "Launcher for gnome-terminal already in the top panel";
else
    /usr/libexec/gnome-panel-add --panel=top_panel --launcher=${HOME}/.gnome2/panel2.d/default/launchers/gnome-terminal.desktop --position=290
fi

cat <<-EOF > ${HOME}/.gnome2/panel2.d/default/launchers/file-browser.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=nautilus --no-desktop --browser %U
Name=File Browser
Icon=/usr/share/icons/gnome/scalable/apps/system-file-manager.svg
EOF
/usr/bin/gconftool-2 --dump /apps/panel/objects | grep file-browser.desktop 2>/dev/null 1>&2
if [ \$? -eq 0 ]; then
    echo "Launcher for nautilus already in the top panel";
else
    /usr/libexec/gnome-panel-add --panel=top_panel --launcher=${HOME}/.gnome2/panel2.d/default/launchers/file-browser.desktop --position=310
fi

cat <<-EOF > ${HOME}/.gnome2/panel2.d/default/launchers/ksystem-monitor.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=ksysguard %U
Name=System Monitor
Icon=/usr/share/icons/gnome/scalable/apps/kde-utilities-system-monitor.svg
EOF
/usr/bin/gconftool-2 --dump /apps/panel/objects | grep ksystem-monitor.desktop 2>/dev/null 1>&2
if [ \$? -eq 0 ]; then
    echo "Launcher for KDE Monitor already in the top panel";
else
    /usr/libexec/gnome-panel-add --panel=top_panel --launcher=${HOME}/.gnome2/panel2.d/default/launchers/ksystem-monitor.desktop --position=860
fi

EODECK
chmod ug+x /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh

Execute the script to add top panel launchers, and test them.

/bin/bash /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh

The top panel will now have extra tools

039_centos_top_panel_after_launchers

Configure the nautilus file browser to show a list view, specific columns and files as well as directories and hidden files.

Examine the default display

nautilus --browser &

Create the configuration script

mkdir -p /media/sf_distros/scripts
cat <<-EODECK > /media/sf_distros/scripts/008_configure_nautilus_file_browser.sh
gconftool-2 -s -t list --list-type string /apps/nautilus/list_view/default_visible_columns "[name,size,type,date_modified,date_accessed,owner,group,where,permissions,octal_permissions]"
gconftool-2 -s -t list --list-type string /apps/nautilus/preferences/default_folder_viewer "[name,size,type,date_modified,owner,group,where,permissions,octal_permissions]"
gconftool-2 -s -t string /apps/nautilus/preferences/default_folder_viewer "list_view"
gconftool-2 -s -t bool /apps/nautilus/sidebar_panels/tree/show_only_directories "false"
gconftool-2 -s -t bool /apps/nautilus/icon_view/default_use_tighter_layout "true"
gconftool-2 -s -t bool /apps/nautilus/compact_view/all_columns_have_same_width "false"
gconftool-2 --type boolean --set /desktop/gnome/file_views/show_hidden_files "true"
EODECK
chmod ug+x /media/sf_distros/scripts/008_configure_nautilus_file_browser.sh

Execute the script

/bin/bash -v /media/sf_distros/scripts/008_configure_nautilus_file_browser.sh

Examine the changes

nautilus --browser &

It is expected that the image being configured a bit at a time in this series of articles will be created more than once for different purposes. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Append “add launchers to top panel and configure nautilus” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# install alacarte and gnome-editor
/bin/bash -v /media/sf_distros/scripts/006_install_local_rpm.sh alacarte

# add launchers to top panel
/bin/bash /media/sf_distros/scripts/007_add_standard_launchers_to_top_panel.sh

# configure nautilus file browser
/bin/bash -v /media/sf_distros/scripts/008_configure_nautilus_file_browser.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Oct 21

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

In this article a script which will add GEyes, ShowDesktop and GnomeMonitor applests and configure the GnomeMonitor applet will be developed and executed.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.

The instructions should work in other RedHat 6-like OS’ and OS versions.

Script Adding Applets to Top Panel

I typically set up my environment to my taste, which does not mean that everybody needs to do this the same way or at all.

The discussion below shows how one can script adding and configuration of top panel applets.

Remember that all this can be done using the relevant UIs but my objective is to create configuration scripts which I can execute and have the demo image configured without having to tediously manipulate various UIs.

Let’s have a look at some applets-related commands and outputs, and then create and execute a script to add three applets to the top panel using a script.

After CentOS installation the top panel looks like that shown in the figure below.

037_centos_top_panel_before

Let’s list top level panels so as to see which ones we have – top and bottom is what is expected.

/usr/bin/gconftool-2 --all-dirs /apps/panel/toplevels

/apps/panel/toplevels/top_panel
/apps/panel/toplevels/bottom_panel

List applets in the two panels

/usr/bin/gconftool-2 --all-dirs /apps/panel/applets

/apps/panel/applets/trash_applet
/apps/panel/applets/workspace_switcher
/apps/panel/applets/window_list
/apps/panel/applets/fast_user_switch_applet
/apps/panel/applets/systray
/apps/panel/applets/gnote
/apps/panel/applets/clock

List all available applets which can be added to the panels

/usr/bin/activation-client -q --spec="has (repo_ids,'IDL:Bonobo/Control:1.0')" | grep '^IID' | cut -d ',' -f1-1 | cut -d ' ' -f2-2 | more

OAFIID:GNOME_MixerApplet
OAFIID:DwellClickApplet
OAFIID:GNOME_SystemTrayApplet
OAFIID:GNOME_NotificationAreaApplet
OAFIID:GNOME_Panel_TrashApplet
OAFIID:GNOME_ClockApplet
OAFIID:GNOME_AccessxStatusApplet
OAFIID:Invest_Applet
OAFIID:GnoteApplet
OAFIID:GNOME_MailcheckApplet
OAFIID:GNOME_CDPlayerApplet
OAFIID:GNOME_FishApplet
OAFIID:GNOME_GeyesApplet
OAFIID:GNOME_GtikApplet
OAFIID:GNOME_WindowMenuApplet
OAFIID:GNOME_KeyboardApplet
OAFIID:GNOME_GWeatherApplet
OAFIID:GNOME_BattstatApplet
OAFIID:GNOME_PagerApplet
OAFIID:GNOME_WorkspaceSwitcherApplet
OAFIID:GNOME_TasklistApplet
OAFIID:GNOME_MultiLoadApplet
OAFIID:GNOME_StickyNotesApplet
OAFIID:GNOME_ShowDesktopApplet
OAFIID:GNOME_WindowListApplet
OAFIID:GNOME_DriveMountApplet
OAFIID:GNOME_CharpickerApplet
OAFIID:GNOME_DictionaryApplet
OAFIID:GNOME_FastUserSwitchApplet
OAFIID:GNOME_GDictApplet
OAFIID:PointerCaptureApplet
OAFIID:GNOME_BrightnessApplet
OAFIID:Square_Controller
OAFIID:Circle_Controller
OAFIID:Bonobo_Sample_Entry
OAFIID:GNOME_CPUFreqApplet
OAFIID:GNOME_MiniCommanderApplet

Create the script to update property values in the applet dump file. This script will be used later to update specific key values. If you are curious, execute the script lines one at a time to see what they do.

mkdir -p /media/sf_distros/scripts
cat <<-'EODECK' > /media/sf_distros/scripts/z_update_upplet_config_key.sh
#!/bin/bash
# update value for key in applet dump for a particular applet
# expect applet dump file, key and value pair as $1, $2 and $3
fileName=${1}
keyName=${2}
valueName=${3}
echo -- before : processing ${fileName}, key: ${keyName}, for value ${valueName}
cat ${fileName} | grep -A 2 "${keyName}<"
matchedLine=$(cat ${fileName} | grep -n "${keyName}<")
matchedLineNum=$(echo ${matchedLine} | cut -d ':' -f 1)
replaceLineNum=$(echo $(( ${matchedLineNum} + 3)))
sed -i "${replaceLineNum}s|<\([a-z]*\)>.*</\([a-z]*\)>|<\1>${valueName}</\1>|" ${fileName}
echo ++ after
cat ${fileName} | grep -A 2 "${keyName}<"
EODECK
chmod ug+x /media/sf_distros/scripts/z_update_upplet_config_key.sh

Create a script which will add three applets to the top bar and configure the monitor applet

mkdir -p /media/sf_distros/scripts
cat <<-'EODECK' > /media/sf_distros/scripts/005_add_applets_to_top_panel.sh
# Add GEyes to the top bar
/usr/libexec/gnome-panel-add --applet=OAFIID:GNOME_GeyesApplet --panel=top_panel --position=849 --copy-launcher

# Add Show Desktop Applet to the top bar
/usr/libexec/gnome-panel-add --applet=OAFIID:GNOME_ShowDesktopApplet --panel=top_panel --position=400 --copy-launcher

# Add Monitor Applet to the top bar
/usr/libexec/gnome-panel-add --applet=OAFIID:GNOME_MultiLoadApplet --panel=top_panel --position=980 --copy-launcher

# Dump applet_2 configuration - that will be the last applet added above - MultiLoadApplet
sleep 2
gconftool-2 --dump /apps/panel/applets/applet_2 > ~/applet_2_fix.entries
sleep 2

# Update property values and load the updated entries
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries view_netload true
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries view_diskload true
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries view_loadavg true
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries view_swapload true
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries view_memload true
/media/sf_distros/scripts/z_update_upplet_config_key.sh ~/applet_2_fix.entries size 30

gconftool-2 --load ~/applet_2_fix.entries
killall gnome-panel

EODECK
chmod ug+x /media/sf_distros/scripts/005_add_applets_to_top_panel.sh

Execute the commands

/bin/bash -v /media/sf_distros/scripts/005_add_applets_to_top_panel.sh

After script execution the top panel looks like the following

038_centos_top_panel_after

List the applets now in the panels

/usr/bin/gconftool-2 --all-dirs /apps/panel/applets
 /apps/panel/applets/clock
 /apps/panel/applets/applet_0
 /apps/panel/applets/applet_1
 /apps/panel/applets/applet_2
 /apps/panel/applets/trash_applet
 /apps/panel/applets/window_list
 /apps/panel/applets/systray
 /apps/panel/applets/workspace_switcher
 /apps/panel/applets/gnote
 /apps/panel/applets/fast_user_switch_applet

It is expected that the image being configured a bit at a time will be created multiple times. With this assumptions the individual scripts are appended to a single script so that the second and subsequent images can be configured by a single script rather than having lots of scripts to execute manually.

Append “add applets to top panel and configure monitor” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# add and configure top panel applets
/bin/bash -v /media/sf_distros/scripts/005_add_applets_to_top_panel.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Oct 21

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

In this article I am creating and executing a script which will disable unneeded services.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.
  2. The user “demo” has sudo access without a password. If this is not the case use the command “su -” and provide the password instead of saying “sudo -i” in the set of commands below

The instructions should work in other RedHat 6-like OS’ and OS versions.

Disable unneeded Services

Create and execute a script which will disable some unneeded services.

Remember that all this can be done manually but my objective is to create configuration scripts which I can execute and have the demo image configured without having to tediously manipulate various UIs.

mkdir -p /media/sf_distros/scripts
cat <<-'EODECK' > /media/sf_distros/scripts/004_disable_unneeded_services.sh
# disable unneeded services
sudo chkconfig postfix off
sudo chkconfig pcscd off
sudo chkconfig openct off
sudo chkconfig bluetooth  off

sudo service postfix stop
sudo service pcscd stop
sudo service openct stop
sudo service bluetooth  stop

EODECK
chmod ug+x /media/sf_distros/scripts/004_disable_unneeded_services.sh

Execute the commands

/bin/bash -v /media/sf_distros/scripts/004_disable_unneeded_services.sh

Append “disable unneeded services” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# disable unneeded services
/bin/bash -v /media/sf_distros/scripts/004_disable_unneeded_services.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
Oct 16

Introduction

Please see the article “Build a Linux-based Infrastructure Solution Demonstration Series” (https://blogs.czapski.id.au/2016/10/build-a-linux-based-infrastructure-solution-demonstration-series) for rationale, introduction and links to articles in this series.

In this article I am disabling the Linux firewall and SELinux-based security in the CentOS 6.8 – this is a demo image, run only sporadically, for short periods of time and typically with no connection to any network, and is typically restored to a snapshot before each execution.

Pre-Requisites

This article assumes that

  1. The work is done in the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image.
  2. The user “demo” has sudo access without a password. If this is not the case use the command “su -” and provide the password instead of saying “sudo -i” in the set of commands below

The instructions should work in other RedHat 6-like OS’ and OS versions.

Disable SELinux Security

Since it is a demo environment disable Firewall and SELinux.

Remember that all this can be done manually but my objective is to create configuration scripts which I can execute and have the demo image configured without having to tediously manipulate various UIs.

mkdir -p /media/sf_distros/scripts
cat <<-'EODECK' > /media/sf_distros/scripts/003_disable_firewall_and_selinux.sh

# disable firewall and selinux
sudo chkconfig iptables off
sudo chkconfig ip6tables off
sudo service iptables stop
sudo service ip6tables stop

# change SELINUX=enforcing to SELINUX=disabled
sudo cp /etc/selinux/config /etc/selinux/config_orig
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

EODECK
chmod ug+x /media/sf_distros/scripts/003_disable_firewall_and_selinux.sh

Execute the commands

/media/sf_distros/scripts/003_disable_firewall_and_selinux.sh

Append “disable firewall and SELinux” script execution commands to the initial bulk configuration script. This script is intended to collect all automated configuration commands and scripts so that they can be all executed in one go on a brand new image if one gets to do this the second and subsequent times.

Don’t actually execute this script while you are building the first image.

cat <<-'EODECK' >> /media/sf_distros/scripts/000_initial_bulk_configuration.sh
# disable firewall and selinux
/media/sf_distros/scripts/003_disable_firewall_and_selinux.sh

EODECK
chmod ug+x /media/sf_distros/scripts/000_initial_bulk_configuration.sh
preload preload preload