Web Application RPM

From SME Server
Revision as of 11:25, 14 September 2007 by Snoble (talk | contribs) (Generic Instructions for building a Web Application RPM)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Generic Instructions for building a Web Application RPM

RPMS make installation more reliable and removal much easier.

This guide aims to create a common structure for building rpms

Build environment

Local Server

Create a build environment on your local server, refer to the SME DevGuide

http://mirror.contribs.org/smeserver/contribs/gordonr/devguide/html/p1082.htm

SME Build Server

When you are comfortable building rpms, you are encouraged to put your source files on the SME Build Server, this allows others to more easily update and improve your rpms.

http://wiki.contribs.org/ReleasingContribs#Submitting_a_contrib_to_the_SME_Server_repository

The Application RPM

Application source

Download the application source, eg foo.tar.gz and place in the SOURCES directory

SPEC file

Edit the following sample .spec file and place in the SPECS directory

%define name foo
%define version 3.6.431
%define release 1
Summary: foo is a helpdesk system
Name: %{name}
Version: %{version}
Release: %{release}%{?dist}
Distribution: SME Server
License: GNU GPL version 2
URL: http://www.fooweb.com
Group: SMEserver/addon
#wget http://www.fooweb.com/downloads/foo-3.6.431.tar.gz
Source: foo-3.6.431.tar.gz
Packager: Stephen Foo <support@foo.net>
BuildArchitectures: noarch
BuildRoot: /var/tmp/%{name}-%{version}
Requires: e-smith-release >= 7.0
AutoReqProv: no

%description
http://foo.org/
foo is a helpdesk system 

%changelog
* Thu Sep 13 2007 Stephen Foo <support@foo.net> 3.6.431-1
- initial release
- builds from unchanged .tar.gz 

%prep
%setup  -c -n %{name}
%build
#drop in an unchanged .tgz, if required rename directory here, eg remove version number.
mkdir -p root/opt/
mv %{name} root/opt/foo

%install
rm -rf $RPM_BUILD_ROOT
(cd root   ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
rm -f %{name}-%{version}-filelist
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \
   --dir '/opt/foo/tempdir/' 'attr(775,www,www)' \
   --file '/opt/foo/logo.gif' 'attr(660,www,www)' \
    > %{name}-%{version}-filelist

%clean
cd ..
rm -rf %{name}

%pre
%preun
%post
%postun

%files -f %{name}-%{version}-filelist
%defattr(-,root,root)
Build the RPM

rpmbuild -ba /home/e-smith/files/users/jim/home/rpms/SPECS/foo.spec


Notes

Add workarounds and alternate methods here ...

Permissions, may need tweaking but usually not many need changing, you don't want the webserver changing the distribution files

SME Intergration RPM

Create database
  • Create password

root/etc/e-smith/db/configuration/migrate/80foo

{
   use MIME::Base64 qw(encode_base64);

   my $rec = $DB->get('foo') || $DB->new_record('foo', {type => 'service'});

   my $pw = $rec->prop('DbPassword');
   return "" if $pw;

   $rec->set_prop('DbPassword', sprintf("%15.0f", int( (1000000000000000) * rand() )));
}
  • Create structure

root/etc/e-smith/templates/etc/e-smith/sql/init/80foo

{
   my $db = $foo{DbName} || 'foo';
   my $user = $foo{DbUser} || 'foo';
   my $pass = $foo{DbPassword} || 'foo';
   $OUT .= <<END
#! /bin/sh
   if [ -d /var/lib/mysql/$db ]; then
     exit
   fi
   /usr/bin/mysql <<EOF
   CREATE DATABASE $db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
   use $db;
   #Insert application specific command to create database structure
   source /opt/foo/sql/mysql_foo.sql;
   use mysql;
   GRANT ALL PRIVILEGES ON $db.* TO $user\@localhost
           IDENTIFIED BY '$pass';
   flush privileges;
EOF
END
}

See the %build section of the spec file where you create the DB name & user.

The %post section of the spec file run the commands to initialise db values and create the db structure

Webserver templates
  • The alias fragment tailored to suit the application

root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

{
    my $status = $foo{'status'} || "disabled";
    return "    # foo is disabled in this VirtualHost"
           unless $status eq 'enabled';

   $OUT = "";
   my $allow = 'all';
   my $pass = '0';
   my $satisfy = 'all';
   my $name = $foo{'Name'} || 'Application Description';
   
   for ('exit-if-none')
   {
     if ($foo{'PublicAccess'})
     {
         if ($foo{'PublicAccess'} eq 'none')
         {
          next;
         }
         elsif ($foo{'PublicAccess'} eq 'local')
         {
           $allow   = $localAccess;
           $pass    = 0;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'local-pw')
         {
           $allow   = $localAccess;
           $pass    = 1;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global')
         {
           $allow   = 'all';
           $pass    = 0;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global-pw')
         {
           $allow   = 'all';
           $pass    = 1;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global-pw-remote')
         {
           $allow   = $localAccess;
           $pass    = 1;
           $satisfy = 'any';
         }
     }
     
     $OUT .= "#------------------------------------------------------------\n";
     $OUT .= "# foo - $name\n";
     $OUT .= "#------------------------------------------------------------\n";
     
     {
       if (exists $foo{'URL'})
       { $OUT .= "Alias  /$foo{'URL'}  /opt/foo\n"; }
     }
     
     $OUT .= "Alias  /foo  /opt/foo\n";
     
     $OUT .= "\n";
     $OUT .= "<Directory /opt/foo>\n";
     $OUT .= "    AddType application/x-httpd-php .php\n";
     $OUT .= "    php_admin_value open_basedir /opt/foo\n";
     $OUT .= "    Options None\n";
     $OUT .= "    order deny,allow\n";
     $OUT .= "    deny from all\n";
     $OUT .= "    allow from $allow\n";
     $OUT .= "    php_value mysql.default_host $foo{DbName}\n";
     $OUT .= "    php_value mysql.default_user $foo{DbUser}\n";
     $OUT .= "    php_value mysql.default_password $foo{DbPassword}\n";
     if ($pass)
     {
         $OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    require valid-user\n";
         $OUT .= "    Satisfy $satisfy\n";
     }
     $OUT .= "</Directory>\n";
   }
}
  • a workaround to enable the application to be located in a domain or subdomain root

root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/80OptDomainFoo

{
   my $status = $foo{'status'} || "disabled";
   return "    # foo-status is disabled.\n"
           unless $status eq 'enabled';

   my $domain = $foo{'domain'} || "disabled";
   return "    # no hostname or domain for foo defined\n"
           if $domain eq 'disabled';

   my $DocRoot = "/opt/foo";

   $OUT  = "";
   $OUT .= "\n";
   $OUT .= "# Redirect an existing hostname or domain to $DocRoot.\n";
   $OUT .= "<VirtualHost 0.0.0.0:80>\n";
   $OUT .= "    ServerName  $domain\n";
   $OUT .= "    DocumentRoot $DocRoot\n";
   $OUT .= "</VirtualHost>\n";
   $OUT .= "<VirtualHost 0.0.0.0:443>\n";
   $OUT .= "    ServerName  $domain\n";
   $OUT .= "    DocumentRoot  $DocRoot\n";
   $OUT .= "    SSLEngine on\n";
   $OUT .= "</VirtualHost>\n";
}
  • a hack to get https to work, a better solution is required

root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30FooAlias

{
   my $status = $foo{'status'} || "disabled";
   return "    # foo is disabled in this VirtualHost"
           unless $status eq 'enabled';

   if ($port eq "443")
   {
      $OUT .= "    ProxyPass /foo http://127.0.0.1/foo\n";
   }
}
System file templates

You may need to create a fragment for a system file such as crontab.

http://mirror.contribs.org/smeserver/contribs/gordonr/devguide/html/c610.htm

Application templates

Place a copy of the application config file in the templates directory,
then overwrite key values, some of which we keep in SME DB's


eg . root\etc\template\opt\foo\config.php

template-begin

{
   $OUT = <<HERE;
<?php
/*
HERE

   $OUT .= 
   Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");

   $OUT .= <<HERE;
*/
HERE

}

template-end

?>

10config-dist

include a copy of the distribution file here

20config-sme

// SME Server Settings
{
   $OUT .= "\$CFG->dbname   = \'$foo{DbName}\'\; \n";
   $OUT .= "\$CFG->dbuser   = \'$foo{DbUser}\'\; \n";
   $OUT .= "\$CFG->dbpass   = \'$foo{DbPassword}\'\; \n";
   $OUT .= "\$CFG->dirroot  = \'/opt/foo'\; \n";
}
Spec file
%define name smeserver-foo
%define version 1.0
%define release 1
Summary: smserver rpm to setup foo, a foo system
Name: %{name}
Version: %{version}
Release: %{release}%{?dist}
Distribution: SME Server
License: GNU GPL version 2
URL: http://www.foo.net/
Group: SMEserver/addon
Source: %{name}-%{version}.tar.gz
#Patch0: smeserver-foo-1.0-null.patch
Packager: Stephen Foo<support@foo.net>
BuildArchitectures: noarch
BuildRequires: e-smith-devtools >= 1.13.1-03
BuildRoot: /var/tmp/%{name}-%{version}
Requires: e-smith-release >= 7.0
Requires: foo
AutoReqProv: no

%description
smserver rpm to setup foo, a helpdesk system

%changelog
* Thu Sep 13 2007 Stephen Foo<support@foo.net> 1.0-1
- initial release

%prep
%setup
#%patch0 -p1

%build
mkdir -p                  root/etc/e-smith/db/accounts/defaults/foo
echo "reserved"         > root/etc/e-smith/db/accounts/defaults/foo/type

mkdir -p                  root/etc/e-smith/db/configuration/defaults/foo
echo "Helpdesk"         > root/etc/e-smith/db/configuration/defaults/foo/Name
echo "global-pw-remote" > root/etc/e-smith/db/configuration/defaults/foo/PublicAccess
echo "enabled"          > root/etc/e-smith/db/configuration/defaults/foo/status
echo "foo"              > root/etc/e-smith/db/configuration/defaults/foo/DbName
echo "foo"              > root/etc/e-smith/db/configuration/defaults/foo/DbUser 

mkdir -p                  root/etc/e-smith/templates.metadata/etc/e-smith/sql/init
echo "PERMS=0750"       > root/etc/e-smith/templates.metadata/etc/e-smith/sql/init/80foo

%install
rm -rf $RPM_BUILD_ROOT
(cd root   ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
rm -f %{name}-%{version}-filelist
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist
echo "%doc COPYING"  >> %{name}-%{version}-filelist

%clean
cd ..
rm -rf %{name}-%{version} 

%pre
%preun
%post
/etc/e-smith/events/actions/initialize-default-databases
/sbin/e-smith/expand-template /etc/e-smith/sql/init/80foo
/etc/rc.d/init.d/mysql.init start
/sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
/usr/bin/sv h /service/httpd-e-smith
/sbin/e-smith/expand-template /opt/foo/config.php
/sbin/e-smith/expand-template /etc/crontab

echo ""
echo "see http://wiki.contribs.org/foo"

%postun
#uninstall
if [ $1 = 0 ] ; then
 /sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
 /usr/bin/sv h /service/httpd-e-smith
 /sbin/e-smith/expand-template /etc/crontab
fi

%files -f %{name}-%{version}-filelist
%defattr(-,root,root)

Further Information

Developer guide

http://wiki.contribs.org/SME_Server:Documentation:Developers_Manual

New DB settings

http://wiki.contribs.org/Moodle#Options