Tuesday, January 04, 2011

System Configuration and Management -- Build a simple RPM that packages a single file

This is an interesting objective - something that I have never had to do before. After looking around at various tutorials and such, the wording of the objective is even more confusing - RPM packages are designed to install programs, not just copy a file. For example, there is a great how-to for creating RPM packages at http://fedoraproject.org/wiki/PackageMaintainers/CreatingPackageHowTo.

A few days looking and I actually came upon a need to create a package - I want to have a silent install of Linux in our datacenter that copies custom scripts to the systems. The best way to handle this would of course be to build an RPM package that included just the one script. A little Googling and bingo! http://lincgeek.org/blog/?p=303 has just the information I needed on how to package a single file and direct it to install into a specific location.

STEP 1: Install the necessary packages
Each site you go to says something different, but it appears that the rpmdevtools contains all you need -- yum install rpmdevtools

STEP 2: Setup the folder structure
mkdir -pv rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS,tmp}

STEP 3: GZip the source file
Assuming you have a script named HelloWorld.sh
  1. Move to the rpm/SOURCES folder
  2. Make a temporary directory with a '-1' at the end -- mkdir HelloWorld-1
  3. GZip the source -- tar czvf HelloWorld-1.tar.gz HelloWorld-1/
STEP 4: Create the spec file
This is the hard part - configuring the RPM on what to build, install, and configure. A sample spec file can be created by running rpmdev-newspec SPECS/HelloWorld.spec, but there is still a lot to add and remove to make this work.
Below is a spec file I created using the sample file
Name:           RandomRootPass
Version:        1
Release:        1%{?dist}
Summary:        Random Root Password changer

Group:          Misc
License:        GPL
#URL:            http://localhost
Source0:        RandomRootPass-1.tar.gz
BuildArch:      noarch
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)


#BuildRequires:
#Requires:

%description
Script to reset the root password to a random value

%prep
%setup -q


%build


%install
#rm -rf $RPM_BUILD_ROOT
#make install DESTDIR=$RPM_BUILD_ROOT
install -m 0755 -d $RPM_BUILD_ROOT/opt/RandomRootPass
install -m 0755 RandomRootPass.pl $RPM_BUILD_ROOT/opt/RandomRootPass/RandomRootPass.pl


%clean
#rm -rf $RPM_BUILD_ROOT


%files
%dir /opt/RandomRootPass
/opt/RandomRootPass/RandomRootPass.pl

#%defattr(-,root,root,-)
#%doc



#%changelog


STEP 5: Build the RPM
Once the spec file is complete, build the package with rpmbuild -qa SPECS/HelloWorld.spec. Assuming no errors occurred, your package is under the RPMS folder. Otherwise attempt to decipher the errors and try again.

4 comments:

Anonymous said...

Hi Ed, could you please confirm all the step are right.
Step 3 is about the HelloWorld.sh script whereas Step 4 is about Random Root Pass
Also the last step... when I run "rpmbuild -qa SPECS/HelloWorld.spec", I get "-qa: unknown option"

Thanks

Anonymous said...

The correct command line is "rpmbuild -ba SPECS/HelloWorld.spec".
You can also try
"rpmbuild -bav SPECS/HelloWorld.spec" for verbose output to give yourself some more information.
You can also use "rpmbuild -bavv..." for more verbose detail.

Anonymous said...

You don't have to use rpmdevtools.

Assuming you are in your home folder and want to build an rpm that packages ~/helloworld.sh:

1. create a directory called myscript-0.1 to hold your script. Copy helloworld.sh under the myscript-0.1 folder
2. tar -cvzf myscript-0.1.tar.gz myscript-0.1
3. create a spec file with 'vim myscript-0.1.spec' (in RHEL6 vim comes with a template for spec files, so whenever you pass it a file ending in .spec it will generate a general purpose spec that you just need to fill out)
4. Run rpmbuild myscript-0.1.spec - this will fail at this point but create the ~/rpmbuild directory structure
5. cp myscript-0.1.tar.gz rpmbuild/SOURCES/ && cp myscript-0.1.spec rpmbuild/SPECS/
6. rpmbuild -ba rpmbuild/SPECS/myscript-0.1.spec (yum install rpm-build if not present)

The spec file would look like this:

Name: myscript
Version: 0.1
Release: 1%{?dist}
Summary: Displays Hello World info
Group: none
License: GPL
URL: http://myscript.example.com
Source0: %{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

BuildRequires: /bin/cp, /bin/rm, /bin/mkdir
Requires: /bin/bash, /bin/echo

%description example RPM, displays Hello World

%prep
%setup -q

%build
echo OK
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/local/bin
cp helloworld.sh $RPM_BUILD_ROOT/usr/local/bin/

%clean
rm -rf $RPM_BUILD_ROOT


%files
%defattr(-,root,root,-)
%attr(0775,root,root) /usr/local/bin/helloworld.sh
%doc

%changelog
* Tue Jun 21 2011 Author 0.1
- Initial RPM

When the RPM is installed it will copy the helloworld script under /usr/local/bin/helloworld.sh with the 0775 permission.

Anonymous said...

Before copy/pasting from a book at least make sure what you are writing is correct...

You don't need the rpmdevtools, that's only a commodity, secondly the command to build a spec is not rpmbuild -qa (wonder where you took that from...)