I'm starting to use yum and apt to manage production and development server configuration, installation, and updates. It's super easy to setup a yum repository and rpms are equally easy to create.
Creating a yum repository
First, setup an empty repository.
]# yum install createrepo
]# mkdir /var/ftp/pub/software/redhat/RPMS/x86_64
]# createrepo /var/ftp/pub/software/redhat/RPMS/x86_64
]# echo "[myrepo]
name=My Repository - Extras
baseurl=file:///var/ftp/pub/software/redhat/RPMS/x86_64
enabled=1
gpgcheck=0
" > /etc/yum.repos.d/myrepo.repo
You now have a repository setup and you have configured your yum client to connect to it using the local file: protocol. The command "yum repolist all" should list the new "My Repository - Extras" repository. If /var/ftp/pub is served by your ftp server then you can also access this repository using ftp:.
Create your rpm packages
Now you have to create rpm's and inject them into the yum repository. For this example I'll create a very basic rpm with a simple rpm dependency.
Overview: To create an rpm you basically choose some location on your dev server called a "Buildroot" which contains a bunch of standard RPM build-related directories, create a .spec file for your new package, place your package sources properly beneath the Buildroot, and finally run rpmbuild -ba to create the rpm binary package. Copy the newly created rpm from the Buildroot to your yum repository and rerun createrepo.
- Create your Buildroot. The default Buildroot location is /usr/src/redhat, but I prefer to create a special unprivileged user to create the rpm packages. I then create the Buildroot beneath the special user's home directory.
]# adduser rpmbuilder
]# su rpmbuilder
]$ mkdir ~/rpms
]$ cd /home/rpmbuilder/rpms && mkdir SPECS SOURCES BUILD RPMS SRPMS
Now create a ~/.rpmmacros file and enter the following into it:
%packager
%vendor
%_topdir /home/rpmbuilder/rpms
The .rpmmacros file allows you to define symbolic variables (identified by a leading '%' character) which can be referenced in your .spec files
- In a normal scenario you would choose a source tarball and create a .spec file for it. Since this is a simple example we're going to create some idealized example tarballs so that we can focus on the rpm-related details rather than the nuances of building a specific software package. These commands will create simple foo-0.0.1.tar.gz and bar-0.0.1.tar.gz source tarballs:
]$ mkdir -p /tmp/foo-0.0.1/opt/foo/
]$ echo "testing" > /tmp/foo-0.0.1/opt/foo/this_file_will_be_installed.foo
]$ cd /tmp/ && tar -cvzf foo-0.0.1.tar.gz foo-0.0.1
]$ mkdir -p /tmp/bar-0.0.1/opt/bar/
]$ echo "testing 2" > /tmp/bar-0.0.1/opt/bar/this_file_will_also_be_installed.bar
]$ cd /tmp/ && tar -cvzf bar-0.0.1.tar.gz bar-0.0.1
Now copy the foo-0.0.1.tar.gz and bar-0.0.1.tar.gz you just created into your /home/rpmbuilder/rpms/SOURCES/ directory. If you were, say, creating an rpm for a binary installation of apache webserver you would obtain the source tarball for apache and place it in the same SOURCES directory. Also, copy the same tarballs into your /var/ftp/pub/software/redhat/SOURCES/ repository directory so that they can be retrieved if you ever needed them again.
]$ cp /tmp/bar-0.0.1.tar.gz /tmp/foo-0.0.1.tar.gz /home/rpmbuilder/rpms/SOURCES/
]$ cp /home/rpmbuilder/rpms/SOURCES/*tar.gz /var/ftp/pub/software/redhat/SOURCES/
- Now create a .spec file for your package. We're going to create 2 packages - "foo" and "bar" - and make foo depend on "bar". The format for a .spec file is "package name"-"package version"-"release number".spec.
]$ touch ~/rpms/SPECS/foo-0.0.1-1.spec
Now open foo-0.0.1-1.spec using your editor, enter the following contents up to (not including) the __END__ token, and save.
%define name foo
%define version 0.0.1
%define release 1
%define vname %{name}-%{version}
Summary: Example Foo
Name: %{name}
Version: %{version}
Release: %{release}
License: Proprietary
Group: ACME
Source: file:///var/ftp/pub/software/redhat/SOURCES/%{vname}.tar.gz
Vendor: %{vendor}
URL: http://your.url.here
Prefix: %{_prefix}
Buildroot: %{_topdir}/%{vname}
Requires: bar = 0.0.1
%description
This does nothing, just testing.
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
install -m 755 -d $RPM_BUILD_ROOT
install -m 755 -d $RPM_BUILD_ROOT/opt
install -m 755 -d $RPM_BUILD_ROOT/opt/foo
install -m 444 opt/foo/this_file_will_be_installed.foo $RPM_BUILD_ROOT/opt/foo/this_file_was_installed.foo
%clean
%files
%dir /opt/foo
%defattr(444, root, root)
/opt/foo/this_file_was_installed.foo
%changelog
* Tue Nov 25 2008 Your Name
- Created rpm package for Foo
__END__
See the RPM HOW-TO for more information about the different macros (like %prep, %setup, %install, %clean, %files) in a .spec file. If you've ever used "make" then the overall structure will be familiar to you. Now repeat for the bar package, creating a bar-0.0.1-1.spec file. You can shortcut this by just doing the following:
]$ cat foo-0.0.1-1.spec | grep -v Requires | sed 's/foo/bar/g' | sed 's/Foo/Bar/g' > bar-0.0.1-1.spec
Now, the following files should exist on your system:
/home/rpmbuilder/rpms/SOURCES/foo-0.0.1.tar.gz
/home/rpmbuilder/rpms/SOURCES/bar-0.0.1.tar.gz
/home/rpmbuilder/rpms/SPECS/foo-0.0.1-1.spec
/home/rpmbuilder/rpms/SPECS/bar-0.0.1-1.spec
- Now you are ready to turn the spec files and tarballs into rpms using the rpmbuild command:
]$ cd /home/rpmbuilder/rpms/SPECS
]$ rpmbuild -ba ./foo-0.0.1-1.spec
]$ rpmbuild -ba ./bar-0.0.1-1.spec
This will create rpm packages in the /home/rpmbuilder/rpms/RPMS/ directory. Copy these rpm files into your repository and regenerate the yum repo metadata.
]# cp /home/rpmbuilder/rpms/RPMS/x86_64/*rpm /var/ftp/pub/software/redhat/RPMS/x86_64/
]# createrepo /var/ftp/pub/software/redhat/RPMS/x86_64
Try to install your new packages using yum
]# yum install foo
Yum should recognize that "foo" depends on the package "bar" and prompt you to accept installing bar as well.
Recent Comments