Showing posts with label Redhat. Show all posts
Showing posts with label Redhat. Show all posts

Friday, July 11, 2025

Real Time at The Edge

 

Edge computing is all the rage now given small devices can often provide the performance required to process the workload in the given edge location.  However before migrating applications and workloads from their existing proprietary systems to a more general Linux environment consumers need to feel confident their workloads will perform just as this did in the legacy systems.   After all some of these systems protect the operators from life or death situations.

Workloads at the edge are often mission critical and perform an elegant orchestrated dance within the confines of their resources.  This might mean some processes share the same processor core and intertwined to ensure each process gets the guaranteed amount of clock cycle but also does not put pressure on other processes on the same core even if the process runs afoul due to an environment or code based problem.

One tool that edge developers can use is called rt-app.  If rt-app doesn't sound familiar, it is a testing tool that can be used to start multiple periodic threads in order to simulate a real-time periodic workload use case.  Not only the sleep and run pattern can be emulated but also the dependency between tasks like accessing same critical resources, creating sequential wake up or syncing the wake up of threads. The use case is described in a json like file which is processed by rt-app.

The rest of this blog will cover an example of testing a real-time group of tasks that run on the same core.  The example will show how we can schedule them without them overlapping and also an example of where a task is broken and it interferes with the the other tasks on the core.  However before I proceed I do want to recognize this work builds upon the efforts Daniel Bristot de Oliveira of Red Hat built out in the following repository.  Daniel was an amazing person to work with and took great strides in explaining things to me that I did not understand.   Unfortunately Daniel passed away a short time after we did this work together  over a year ago.   I have greatly missed him as a colleague, mentor and friend.

Contents of Repository

The repository for the work described is located here and consists of the following:
  • Dockerfile - To build the container to run the tests
  • entrypoint.sh - The script that runs within the container to kickoff the rt-app workload test
  • run.sh - The script that takes Daniel's work here and collapses it into one script and launches rt-app via containers.
  • basic.json - This is used to compute the CAL (Function Call Interrupt) on a core
  • single.json - Example json
  • template.json - Example json

Build the Container

We can build the container using the files in the repository. This container build process has been tested on both x86_64 and aarch64.

# podman build -f Dockerfile --build-arg ARCH=`uname -i` -t quay.io/bschmaus/rt-app-container:latest [1/2] STEP 1/7: FROM registry.access.redhat.com/ubi9/ubi-minimal:9.3 AS builder [1/2] STEP 2/7: RUN echo "builder:x:1001:" >> /etc/group && echo "builder:x:1001:1001:Builder:/home/build:/bin/bash" >> /etc/passwd && install -o builder -g builder -m 0700 -d /home/build --> Using cache 3a05dd8b2a4da05ef3af9f0ed71ad3033f7f9ecd36c1554a9fc12237f39a41a6 --> 3a05dd8b2a4d (...) [2/2] STEP 11/11: ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] [2/2] COMMIT quay.io/bschmaus/rt-app-container:latest --> c7764c58580b Successfully tagged quay.io/bschmaus/rt-app-container:latest c7764c58580b549c18f1a2cf59194e8657620d12289573861640f608b9f0a1fe

Test Framework

We will be doing our testing on a Red Hat Enterprise Linux 9.3 system with low latency tuned profiles.

# uname -a Linux edge-24.edge.lab.eng.rdu2.redhat.com 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Oct 3 11:12:36 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux # cat /etc/redhat-release Red Hat Enterprise Linux release 9.3 (Plow)

The first step we need to perform is to install the tuned-profiles-realtime and tuned. I should note here that for aarch64 I needed to manually download the tuned-profiles-realtime from Red Hat Portal because even though the rpm package is a noarch it is only available in the x86_64 repos.

# dnf install tuned tuned-profiles-realtime Updating Subscription Management repositories. Last metadata expiration check: 0:55:11 ago on Tue 23 Apr 2024 01:02:02 PM EDT. Package tuned-2.21.0-1.el9_3.noarch is already installed. Dependencies resolved. ============================================================================================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================================================================================== Installing: tuned-profiles-realtime noarch 2.21.0-1.el9_3 beaker-NFV 15 k Installing dependencies: tuna noarch 0.18-12.el9 beaker-BaseOS 166 k Transaction Summary ============================================================================================================================================================================================================================================== Install 2 Packages Total download size: 182 k Installed size: 590 k Is this ok [y/N]: y Downloading Packages: (1/2): tuned-profiles-realtime-2.21.0-1.el9_3.noarch.rpm 1.7 MB/s | 15 kB 00:00 (2/2): tuna-0.18-12.el9.noarch.rpm 14 MB/s | 166 kB 00:00 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 14 MB/s | 182 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : tuna-0.18-12.el9.noarch 1/2 Installing : tuned-profiles-realtime-2.21.0-1.el9_3.noarch 2/2 Running scriptlet: tuned-profiles-realtime-2.21.0-1.el9_3.noarch 2/2 Verifying : tuna-0.18-12.el9.noarch 1/2 Verifying : tuned-profiles-realtime-2.21.0-1.el9_3.noarch 2/2 Installed products updated. Installed: tuna-0.18-12.el9.noarch tuned-profiles-realtime-2.21.0-1.el9_3.noarch Complete!

With the tuned profiles installed lets determine which cores we would like to set isolated.

# numactl --hardware available: 1 nodes (0) node 0 cpus: 0 1 2 3 4 5 6 7 node 0 size: 63628 MB node 0 free: 60714 MB node distances: node 0 0: 10

Since everything is in one NUMA here we are just going to isolate cores 4-7 for our testing. To prepare for that we need to edit the following file /etc/tuned/realtime-variables.conf and set the isolcpus. Since the default setting in the file is isolated_cores=\${f:calc_isolated_cores:1} we can use a simple sed to make our change.

# sed -i s/isolated_cores=\${f:calc_isolated_cores:1}/isolated_cores=4-7/g /etc/tuned/realtime-variables.conf # cat /etc/tuned/realtime-variables.conf|grep ^isolated_cores isolated_cores=4-7

Now let's set the tuned profile and reboot for the changes to take effect.

# tuned-adm profile realtime # reboot

To capture a kernel trace which we can view with KernelShark we will need to install trace-cmd

# dnf install -y trace-cmd Updating Subscription Management repositories. Last metadata expiration check: 1:43:35 ago on Tue 23 Apr 2024 01:02:02 PM EDT. Dependencies resolved. ============================================================================================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================================================================================== Installing: trace-cmd x86_64 2.9.2-10.el9 beaker-BaseOS 233 k Installing dependencies: libtracecmd x86_64 0-10.el9 beaker-BaseOS 100 k libtracefs x86_64 1.3.1-1.el9 beaker-BaseOS 75 k Transaction Summary ============================================================================================================================================================================================================================================== Install 3 Packages Total download size: 408 k Installed size: 893 k Is this ok [y/N]: y Downloading Packages: (1/3): libtracecmd-0-10.el9.x86_64.rpm 6.4 MB/s | 100 kB 00:00 (2/3): libtracefs-1.3.1-1.el9.x86_64.rpm 4.2 MB/s | 75 kB 00:00 (3/3): trace-cmd-2.9.2-10.el9.x86_64.rpm 11 MB/s | 233 kB 00:00 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 19 MB/s | 408 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : libtracefs-1.3.1-1.el9.x86_64 1/3 Installing : libtracecmd-0-10.el9.x86_64 2/3 Installing : trace-cmd-2.9.2-10.el9.x86_64 3/3 Running scriptlet: trace-cmd-2.9.2-10.el9.x86_64 3/3 Verifying : libtracecmd-0-10.el9.x86_64 1/3 Verifying : libtracefs-1.3.1-1.el9.x86_64 2/3 Verifying : trace-cmd-2.9.2-10.el9.x86_64 3/3 Installed products updated. Installed: libtracecmd-0-10.el9.x86_64 libtracefs-1.3.1-1.el9.x86_64 trace-cmd-2.9.2-10.el9.x86_64 Complete!

Running a Test

After we have built our container and have installed and configured out how we can run a test. The run.sh script can perform three different tests which are defined by the TYPE variable inside the script. Those tests are: single, three and broken. In our test below we set the TYPE to three and CPUS to core 5. Then ran the test which looks like the following:

# ./run.sh Enable DEADLINE hrtick... Allow real-time tasks may use up to 100% of CPU times... sysctl: setting key "kernel.sched_rt_runtime_us": Device or resource busy Set preemptive scheduling to full... Creating log and json directories... Set variable values for run... Measure the CAL for core 5... Build up test json files... Create and run the pods... 34e09802149a25585d54f7ed2117202b69afa5619c08312e19e190d174a2842b UN-container 5763bf6938629ef3cb2985a927a7978a64617fe0e937543b2b752b588507f773 DEUX-container 70671f8e1b42a7548f6515399ac8e3a8ad4087285e39e2ffcc049ef5db847df3 TROIS-container Gather the trace-cmd recording... CPU0 data recorded at offset=0xaba000 294912 bytes in size CPU1 data recorded at offset=0xb02000 520192 bytes in size CPU2 data recorded at offset=0xb81000 360448 bytes in size CPU3 data recorded at offset=0xbd9000 303104 bytes in size CPU4 data recorded at offset=0xc23000 0 bytes in size CPU5 data recorded at offset=0xc23000 39940096 bytes in size CPU6 data recorded at offset=0x323a000 0 bytes in size CPU7 data recorded at offset=0x323a000 0 bytes in size Cleanup the pods... 5763bf6938629ef3cb2985a927a7978a64617fe0e937543b2b752b588507f773 34e09802149a25585d54f7ed2117202b69afa5619c08312e19e190d174a2842b 70671f8e1b42a7548f6515399ac8e3a8ad4087285e39e2ffcc049ef5db847df3

Once the test has run take the trace.dat output and look at it in KernelShark and make sure that the iterations and cycles do not overrun one another.

Thursday, January 02, 2025

Practical Example of Red Hat Image Mode: Bootc

Red Hat Image Mode is a new approach to operating system (OS) deployment that lets users build, deploy, and manage Red Hat Enterprise Linux as a bootc container image. It reduces complexity across the enterprise by letting development, operations, and solution providers use the same container-native tools and techniques to manage everything from applications to the underlying OS.

The following blog is the step by step process I took to create a Bootc image mode iso image. The following steps were carried out on a Red Hat Enterprise Linux 9.4 host as root though sudo and a regular user could also be used.

The first requirement was getting the container tools and so I used the following to get those installed.

# dnf install container-tools Updating Subscription Management repositories. Last metadata expiration check: 2:20:17 ago on Fri 26 Jul 2024 07:17:27 AM CDT. Dependencies resolved. ============================================================================================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================================================================================== Installing: container-tools noarch 1-14.el9 rhel-9-for-x86_64-appstream-rpms 8.3 k Upgrading: aardvark-dns x86_64 2:1.10.0-3.el9_4 rhel-9-for-x86_64-appstream-rpms 969 k buildah x86_64 2:1.33.7-3.el9_4 rhel-9-for-x86_64-appstream-rpms 9.4 M netavark x86_64 2:1.10.3-1.el9 rhel-9-for-x86_64-appstream-rpms 4.0 M podman x86_64 4:4.9.4-6.el9_4 rhel-9-for-x86_64-appstream-rpms 16 M Installing dependencies: cockpit-podman noarch 84.1-1.el9 rhel-9-for-x86_64-appstream-rpms 683 k podman-docker noarch 4:4.9.4-6.el9_4 rhel-9-for-x86_64-appstream-rpms 106 k podman-remote x86_64 4:4.9.4-6.el9_4 rhel-9-for-x86_64-appstream-rpms 10 M python3-podman noarch 3:4.9.0-1.el9 rhel-9-for-x86_64-appstream-rpms 178 k python3-pyxdg noarch 0.27-3.el9 rhel-9-for-x86_64-appstream-rpms 108 k python3-tomli noarch 2.0.1-5.el9 rhel-9-for-x86_64-appstream-rpms 37 k skopeo x86_64 2:1.14.3-0.1.el9 rhel-9-for-x86_64-appstream-rpms 8.5 M toolbox x86_64 0.0.99.5-2.el9 rhel-9-for-x86_64-appstream-rpms 2.5 M udica noarch 0.2.8-1.el9 rhel-9-for-x86_64-appstream-rpms 54 k Transaction Summary ============================================================================================================================================================================================================================================== Install 10 Packages Upgrade 4 Packages Total download size: 52 M Is this ok [y/N]: y Downloading Packages: (1/14): container-tools-1-14.el9.noarch.rpm 29 kB/s | 8.3 kB 00:00 (2/14): python3-tomli-2.0.1-5.el9.noarch.rpm 126 kB/s | 37 kB 00:00 (3/14): python3-pyxdg-0.27-3.el9.noarch.rpm 347 kB/s | 108 kB 00:00 (4/14): cockpit-podman-84.1-1.el9.noarch.rpm 3.0 MB/s | 683 kB 00:00 (5/14): udica-0.2.8-1.el9.noarch.rpm 616 kB/s | 54 kB 00:00 (6/14): python3-podman-4.9.0-1.el9.noarch.rpm 1.3 MB/s | 178 kB 00:00 (7/14): podman-docker-4.9.4-6.el9_4.noarch.rpm 1.2 MB/s | 106 kB 00:00 (8/14): toolbox-0.0.99.5-2.el9.x86_64.rpm 4.6 MB/s | 2.5 MB 00:00 (9/14): netavark-1.10.3-1.el9.x86_64.rpm 4.4 MB/s | 4.0 MB 00:00 (10/14): aardvark-dns-1.10.0-3.el9_4.x86_64.rpm 3.3 MB/s | 969 kB 00:00 (11/14): skopeo-1.14.3-0.1.el9.x86_64.rpm 3.9 MB/s | 8.5 MB 00:02 (12/14): podman-remote-4.9.4-6.el9_4.x86_64.rpm 3.2 MB/s | 10 MB 00:03 (13/14): buildah-1.33.7-3.el9_4.x86_64.rpm 3.5 MB/s | 9.4 MB 00:02 (14/14): podman-4.9.4-6.el9_4.x86_64.rpm 5.3 MB/s | 16 MB 00:02 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 9.6 MB/s | 52 MB 00:05 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Upgrading : aardvark-dns-2:1.10.0-3.el9_4.x86_64 1/18 Upgrading : netavark-2:1.10.3-1.el9.x86_64 2/18 Upgrading : podman-4:4.9.4-6.el9_4.x86_64 3/18 Installing : skopeo-2:1.14.3-0.1.el9.x86_64 4/18 (...) Verifying : podman-4:4.9.4-6.el9_4.x86_64 17/18 Verifying : podman-2:4.6.1-8.el9_3.x86_64 18/18 Installed products updated. Upgraded: aardvark-dns-2:1.10.0-3.el9_4.x86_64 buildah-2:1.33.7-3.el9_4.x86_64 netavark-2:1.10.3-1.el9.x86_64 podman-4:4.9.4-6.el9_4.x86_64 Installed: cockpit-podman-84.1-1.el9.noarch container-tools-1-14.el9.noarch podman-docker-4:4.9.4-6.el9_4.noarch podman-remote-4:4.9.4-6.el9_4.x86_64 python3-podman-3:4.9.0-1.el9.noarch python3-pyxdg-0.27-3.el9.noarch python3-tomli-2.0.1-5.el9.noarch skopeo-2:1.14.3-0.1.el9.x86_64 toolbox-0.0.99.5-2.el9.x86_64 udica-0.2.8-1.el9.noarch Complete!

Once the tooling is in place we need to login to register.redhat.io with a Red Hat account.

# podman login registry.redhat.io Username: myusername Password: Login Succeeded!

Next we need to pull two images for this workflow locally:

  • The latest Red Hat Bootc Image Builder image
  • The latest Red Hat Bootc image

First let's pull the image builder image.

# sudo podman pull registry.redhat.io/rhel9/bootc-image-builder Trying to pull registry.redhat.io/rhel9/bootc-image-builder:latest... Getting image source signatures Checking if image destination supports signatures Copying blob edab65b863ae done | Copying blob ce39a10ee5db done | Copying blob 6e743249fd30 done | Copying config 7e467a06cb done | Writing manifest to image destination Storing signatures 7e467a06cbc49d0e601ab5acad54afcf16c7fd3187296c74f2780ec3e758977a

Then we can pull the Red Hat Enterprise Linux Bootc image. Note if there is a need to build a custom Bootc image that can also be done as well and is documented here

# podman pull registry.redhat.io/rhel9/rhel-bootc:latest Trying to pull registry.redhat.io/rhel9/rhel-bootc:latest... Getting image source signatures Checking if image destination supports signatures Copying blob b696b6658912 done | Copying blob b696b6658912 done | Copying blob e0b929cd893f done | (...) Copying blob 2942d3f50802 done | Copying blob 8ea0992b56d4 done | Copying blob ad312c5c40cc done | Copying blob bd9ddc54bea9 done | Copying config 482f4c67cc done | Writing manifest to image destination Storing signatures 482f4c67cc158fa4b8db27c09832d3133bc45b1d989aa6d166ca2ef45f6c7178

Once we have pulled our images let's just review what we have with podman images.

# podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/rhel9/rhel-bootc latest 482f4c67cc15 4 days ago 1.47 GB registry.redhat.io/rhel9/bootc-image-builder latest 7e467a06cbc4 4 days ago 521 MB

Next I created a directory structure under root home directory.

# mkdir ~/bootc # cd bootc # mkdir output

I also created a config.toml file which allows us to customize the image. In this example I embedding my user/password, public ssh-key and the groups I should belong to.

# cat <<EOL > config.toml [[blueprint.customizations.user]] name = "myuser" password = "password" key = "ssh-rsa publick-key" groups = ["wheel"] EOL

Before we begin building let's review where we are and what is in the directory structure.

# pwd
/root/bootc
# ls
config.toml  output

Before we begin the build process we need to workaround an issue here by removing the signatures in our local copy of the RHEL Bootc image.

# skopeo copy --remove-signatures containers-storage:registry.redhat.io/rhel9/rhel-bootc:latest containers-storage:registry.redhat.io/rhel9/rhel-bootc:latest INFO[0000] Not using native diff for overlay, this may cause degraded performance for building images: kernel has CONFIG_OVERLAY_FS_REDIRECT_DIR enabled Copying blob f2d952b04649 skipped: already exists Copying blob bc1abff2c8d4 skipped: already exists Copying blob 491341ca1509 skipped: already exists (...) Copying blob 6c118cde0f5c skipped: already exists Copying blob 5f70bf18a086 skipped: already exists Copying blob 12787d84fa13 skipped: already exists Copying config 482f4c67cc done | Writing manifest to image destination

If everything looks good we can proceed to run the build process which consists of using podman to run the bootc-image-builder while passing in some directories and referencing the starting image we will use to build our ISO. The entire build process happens within a container and the ISO generated is dumped to the output directory we have mapped into the container. The process will take a bit to run and the log output is very long. I have provided the complete log run here with the condensed version below.

# podman run --rm -it --privileged --security-opt label=type:unconfined_t -v /var/lib/containers/storage:/var/lib/containers/storage -v /root/bootc/output:/output -v /root/bootc/config.toml:/config.toml registry.redhat.io/rhel9/bootc-image-builder --type iso --config /config.toml --local registry.redhat.io/rhel9/rhel-bootc:latest Generating manifest manifest-iso.json DONE Building manifest-iso.json starting -Pipeline source org.osbuild.containers-storage: 51102953cf5005007cf8b3bd76c39a0ae558aa34f311915042cdc0bc4c1fb246 Build root: <host> Pipeline source org.osbuild.curl: 07337b98b3c859adfb37b011d83cf0511884147bf999e7869ffbf9074b529a4f Build root: <host> (...) Writing to 'stdio:/run/osbuild/tree/install.iso' completed successfully. ⏱ Duration: 3s org.osbuild.implantisomd5: bf37713d1bdb752cb80271b8243583e86665b003c69abff0e1730de24398fac1 { "filename": "install.iso" } ['implantisomd5', '/run/osbuild/tree/install.iso'] Inserting md5sum into iso image... md5 = 11cf490ec817e7904ba35961d5323195 Inserting fragment md5sums into iso image... fragmd5 = 4f7338c869faf1a2881d46dc4ac1eebf46148d4bf2fa1d59149d74f43195 frags = 20 Setting supported flag to 0 ⏱ Duration: 3s manifest - finished successfully build: 9133fb8610ab053dae7e281e6a6655dbb912c4530d32e4da75c06b8713a87c80 anaconda-tree: fcd61d1236a42900977530f12f45fe452f2f0c8bf3c80a7ba60cb45ffe4bf36d rootfs-image: 0a517e05ab42f947beec8dae4d2da338ca9cc7fe17b1daba013e24b1c60aeadf efiboot-tree: 61a20c820b40436ce7bd6d1a74c6b97a05f7c8800b678083942e814cf9f7cc0e bootiso-tree: 53d4713e1d036ca2d06ae3b0b64c8b9a4efb63cbc6fed4f13afe1e984b7af04d bootiso: bf37713d1bdb752cb80271b8243583e86665b003c69abff0e1730de24398fac1 Build complete! Results saved in .

Once the build process completes we will find an install.iso in the output/bootiso/ directory.

# cd ~/bootc/output/bootiso/ # ls -l total 2211840 -rw-r--r--. 1 root root 2264924160 Jul 26 10:38 install.iso

The installation iso that was created can then be used to install RedHat Enterprise Linux on another host automatically and rather quickly compared to the old package based method.

Hopefully this provides a simple example to understand the concept of building and consuming Red Hat Image Mode.

Sunday, May 24, 2015

Deleting Duplicate Hosts In Satellite or Spacewalk


Sometimes when you register hosts to Satellite or Spacewalk you end up with duplicate hosts being registered.   The old one that will no longer check in and just be an orphan and a new one which will check in and get updates and packages.   I saw this behavior a lot in environments where people were using Vagrant and/or Openstack where they would continuously launch the same host with the same hostname and register it to Satellite. 

The script  below can be used to clean out those duplicate hosts and can be setup to run from cron daily.   The script assumes you run this as the root user and have configured root to run spacecmd without specifying username and password at the command line.  This was tested with Satellite 5.6.

#!/usr/bin/perl
### Delete duplicate hosts in Satellite or Spacewalk via Spacecmd ###
@duphosts = `spacecmd -q system_list | uniq -d`;
foreach $system (@duphosts) {
        chomp($system);
        $spacecmd = `spacecmd system_details $system 2>&1 |grep $system |grep =|sed 's/^.*=/=/'`;
        $spacecmd =~ s/\s+//g;
        $spacecmd =~ s/=//g;
        @ids = split(/\,/,$spacecmd);
        $count=0;
        foreach $ids (@ids) {
                chomp($ids);
                $count++;
                if ($count > $#ids) {
                        print "Duplicates removed for system: $system\n";
                        last;
                }
                $cmd = `spacecmd -y system_delete $ids`;
                print "$cmd\n";
                sleep (2);
        }
        print "Cleanup of $system complete...\n";
}
print "Cleanup of Satellite complete!\n";

Syncing Redhat Repos With Pulp


The following is a basic installation/configuration guide to setting up Pulp to pull package channels from Redhat's CDN(Content Delivery Network) so that you can leverage Spacewalk, Suse Manager or another repository manager that would not normally be able to access Redhat directly.

Assumptions:  This assumes you are installing Pulp on Redhat 6.6, although I don;t see why this would not work on Redhat 7.0 or another Linux distro for that matter.  The only changes would be the switch from init scripts to systemd in the below documentation.

1)  Register the host with Redhat directly to receive its updates:
      #subscription-manager register --force
      #subscription-manager refresh
      #subscription-manager subscribe --auto

2) Run an update to confirm you can access the Redhat repos properly:
     #yum upgrade

3) Install the Pulp repo and the Linux Epel repo as you will need packages from both:
    #rpm -Uvh https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    #rpm -Uvh http://repos.fedorapeople.org/repos/pulp/pulp/rhel-pulp.repo

4) Install, enable and install mongodb server:
    #yum install mongodb-server
    #service mongod start
    #chkconfig mongod on

5) Install, enable and start qpidd:
    #yum install qpid-cpp-server qpid-cpp-server-store
    #service qpidd start
    #service qpidd on
    #chkconfig qpidd on

6) Install Pulp group of packages:
    #yum groupinstall pulp-server-qpid

7) Run Pulp database setup to populate Pulp database:
    #sudo -u apache pulp-manage-db

8) Enable and start web service:
    #service httpd start
    #chkconfig httpd on
    #systemctl enable httpd

9) Enable and start pulp workers, celery beat and pulp resource manager:
    #chkconfig pulp_workers on
    #service pulp_workers start
    #chkconfig pulp_celerybeat on
    #service pulp_celerybeat start
    #chkconfig pulp_resource_manager on 
    #service pulp_resource_manager start

10) Install pulp-admin packages:
      #yum groupinstall pulp-admin

11) Install Pulp consumer qpid package:
      #yum groupinstall pulp-consumer-qpid

12) Edit Pulp admin.conf, consumer.conf and agent.conf to your specifications:
      #vi /etc/pulp/admin/admin.conf
      #vi /etc/pulp/consumer/consumer.conf
      #vi /etc/pulp/agent/agent.conf

At this point Pulp should be ready to consume something from the Redhat Content Delivery Network.   Lets see what setting up a sync looks like in the following steps.

1) Create a repo with the feed location and the correct certs and keys related to accessing that repo feed.
    #pulp-admin rpm repo create --repo-id=rhel-6-server-rpms --feed=https://cdn.redhat.com/content     /dist/rhel/server/6/6Server/x86_64/os --feed-ca-cert=/etc/rhsm/ca/redhat-uep.pem --feed-key=/etc/pki/entitlement/5161085288703435774-key.pem --feed-cert=/etc/pki/entitlement/5161085288703435774.pem

2) (Optional) Configure the repo you created with the number of download workers and max download speed.   This helps if you are pulling packages down over a smaller WAN link and do not want to saturate it.
    #pulp-admin rpm repo update --max-speed=14000 --repo-id=rhel-6-server-rpms
    #pulp-admin rpm repo update --max-downloads=2 --repo-id=rhel-6-server-rpms

3) Configure the repo so that it is served up via the web server so it can be consumed via HTTP:
    #pulp-admin rpm repo update --repo-id=rhel-6-server-rpms  --serve-http=true

4) Sync the repo from the source, in this case in our example Redhat:
    #pulp-admin rpm repo sync run --repo-id=rhel-6-server-rpms

5) (Optional) Setup the sync in step 4 in a cron job to occasionally sync the newer packages to keep your Pulp repo up to date.







Wednesday, December 31, 2014

x86 Hardware RAID Traps with BS_RAID_CHK


The following script is designed to run on Solaris x86 or Redhat systems with LSI and Adaptec hardware controllers.  It will check for degraded states of those controllers using mpt-status, arccon or raidctl depending on hardware vendor and OS.   If a degraded state is found it will send an snmptrap to your snmptrap collector.

#!/usr/bin/perl
#################################################################
# Script checks status of hardware raid on X86 hardware        #
# Supported OS's: Solaris x86, Redhat                #
# Supported Controller's: LSI & Adaptec                #
# Note: Requires mpt-status for LSI                #
# Note: Requires arccon for adaptec                #
# Note: Requires raidctl for Solaris x86            #
# Sends trap if degraded state                    #
#################################################################
use strict;
my $prefix = "bs_raid_chk";
my $servicechk = "unix_traps";
my $community = "asdpublic";
my $manager = "10.66.65.23";
my $raidctl = '/usr/sbin/raidctl';
my $mptstatus = '/usr/sbin/mpt-status';
my $arcconf = '/usr/StorMan/arcconf';
my (@components,@command);
my ($num,$status,$sendtrap,$volume);
### If Solaris System use this check ###
if (`uname -a` =~ /SunOS/) {
    if ( -e $raidctl) {
        @command = `$raidctl -S`;
        foreach (@command) {
            chomp();
            @components = split();
            $num = $components[1] + 2;
            $status = "$components[$#components] - Controller: $components[0], RAID: $components[$num], Number of Disks: $components[1]\n";
            if ($_ =~ /DEGRADED/) {
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.CRITICAL";
                system "/usr/sfw/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1005 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                        exit;
            } elsif ($_ =~ /SYNC/) {
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                                system "/bin/touch /tmp/$prefix.WARNING";
                system "/usr/sfw/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1006 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                        exit;
            } elsif ($_ =~ /OPTIMAL/) {
                if ( !-e "/tmp/$prefix.OK" ) {
                    system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                    system "/bin/touch /tmp/$prefix.OK";
                    system "/usr/sfw/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1007 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                }
            }
        }
    }
}
### If Linux system use this check  ###
if (`uname -a` =~ /Linux/) {
    # If system has LSI controller, then mptstatus should be installed
    if (-e $mptstatus) {
        my $modstatus = `/sbin/lsmod |grep mptctl|wc -l`;
        chomp($modstatus);
        if ($modstatus eq "0") {
            my $modload = `/sbin/modprobe mptctl`;
            $modstatus = `/sbin/lsmod |grep mptctl|wc -l`;
            chomp($modstatus);
            if ($modstatus eq "0") { print "ABORT: Failed to load mptctl module.\n";exit;}
        }
        my $controller = `$mptstatus -p -s|grep Found`;
        chomp($controller);
        my ($id,$junk) = split(/,/,$controller);
        $id =~ s/Found SCSI id=//g;
        @command = `$mptstatus -i $id -s`;
        $status="";
        foreach (@command) {
            chomp();
            $status = "$status $_";   
        }
        $status = "$status";
        #print "$status\n";
        foreach (@command) {
            chomp();
            if ( $_ =~ /DEGRADED/ ) {
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.CRITICAL";   
                system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1005 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                exit;
            } elsif ($_ =~ /SYNC/ ) {
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.WARNING";
                system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1006 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                exit;
            } elsif ($_ =~ /OPTIMAL/ ) {
                if ( !-e "/tmp/$prefix.OK" ) {
                    system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                    system "/bin/touch /tmp/$prefix.OK";
                    system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1007 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                }
            }
        }
    }
    # if system has Adaptec controller then arcconf should be installed
    if ( -e $arcconf ) {
        @command = `$arcconf getconfig 1|grep Status|grep :`;
        foreach (@command) {
            if (( $_ =~ /Controller Status/ ) && ($_ !~ /Optimal/ )) {
                $status = "Controller not optimal";
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.CRITICAL";
                system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1005 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                exit;
            }
            if (( $_ =~ /  Status  / ) && ($_ !~ /Optimal/ )) {
                $status = "Battery not optimal";
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.WARNING";
                system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1006 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                exit;
            }
            if (( $_ =~ /Status of logical device/) && ($_ !~ /Optimal/ )) {
                $status = "Logical HW RAID Volume not optimal";
                system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                system "/bin/touch /tmp/$prefix.CRITICAL";
                system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1005 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                exit;
            }
            if ( $_ =~ /Optimal/ ) {
                if ( !-e "/tmp/$prefix.OK" ) {
                    $status = "Hardware RAID - OK";
                    system "/bin/rm /tmp/$prefix.* >/dev/null 2>&1";
                    system "/bin/touch /tmp/$prefix.OK";
                    system "/usr/bin/snmptrap -v 2c -c $community $manager '' .1.3.6.1.4.1.11.2.17.1.0.1007 .1.3.6.1.4.1.11.2.17 s \"$servicechk\" .1.3.6.1.4.1.11.2.17 s \"$status\"";
                }
            }
        }
    }   
}
exit; 


Friday, November 30, 2007

Replacing Failed Disk in Linux Software Raid


When I worked at the University of Minnesota we used IBM x86 servers and since well it was the University we didn't buy a lot of systems with hardware raid.   This meant that software raid in Linux was the rage.   Unfortunately the team I worked with never really documented the process very well and so the following write up takes a practical example and illustrates the steps.

Overview:

 1) Determine which disk has failed.
 2) Remove failed disk from metadevice using mdadm. 
 3) Physically replace disk. 
 4) Partition new disk using sfdisk. 
 5) Add new disk back into raid metadevice using mdadm. 
 6) Confirm array is rebuilding by "cat /proc/mdstat". 

 Example: 

 1) Below, md3 and md4 have a failed device sdc, which contains slices sdc1 and sdc2.
#cat /proc/mdstat Personalities : [raid1] [raid5] read_ahead 1024 sectors Event: 5 md2 : active raid1 sdb1[1] sda1[0] 80192 blocks [2/2] [UU] resync=DELAYED md0 : active raid1 sdb2[1] sda2[0] 2096384 blocks [2/2] [UU] resync=DELAYED md1 : active raid1 sdb3[1] sda3[0] 33366912 blocks [2/2] [UU] [===>.................] resync = 16.5% (5511296/33366912) finish=46.2min speed=10027K/sec md3 : active raid5 sde1[2] sdd1[1] 35342720 blocks level 5, 64k chunk, algorithm 0 [3/2] [_UU] md4 : active raid5 sde2[2] sdd2[1] 35744384 blocks level 5, 64k chunk, algorithm 0 [3/2] [_UU]
2) We need to use mdadm to remove failed slices from array. Note this is not always needed, but we will show example for practicle purposes.
#mdadm -r /dev/md3 /dev/sdc1 #mdadm -r /dev/md4 /dev/sdc2
3) Physically remove the disk(s) from the system. 4) Partition the new disk, using a partition table from another member(device) of the array. This example will use /dev/sde and we will dump partition table out to a file and then read it into the new device using sfdisk.
#sfdisk -d /dev/sde>/tmp/partition.out #sfdisk /dev/sdc
5) Add the device slices back into corresponding raid metadevice using mdadm.
#mdadm -a /dev/md3 /dev/sdc1 #mdadm -a /dev/md4 /dev/sdc2
6) Cat /proc/mdstat for results.
#cat /proc/mdstat Personalities : [raid1] [raid5] read_ahead 1024 sectors Event: 8 md2 : active raid1 sdb1[1] sda1[0] 80192 blocks [2/2] [UU] resync=DELAYED md0 : active raid1 sdb2[1] sda2[0] 2096384 blocks [2/2] [UU] resync=DELAYED md1 : active raid1 sdb3[1] sda3[0] 33366912 blocks [2/2] [UU] [==========>..........] resync = 52.8% (17633280/33366912) finish=25.6min speed=10228K/sec md3 : active raid5 sdc1[3] sde1[2] sdd1[1] 35342720 blocks level 5, 64k chunk, algorithm 0 [3/2] [_UU] [============>........] recovery = 60.9% (10776268/17671360) finish=11.2min speed=10233K/sec md4 : active raid5 sdc2[3] sde2[2] sdd2[1] 35744384 blocks level 5, 64k chunk, algorithm 0 [3/2] [_UU]
Note: md4 will not start rebuilding until md3 is complete, since both raids contain slices from the same physical disk.