From Fedora Project Wiki
This page is a draft only
It is still under construction and content may change. Do not rely on the information on this page.

Changelog

0.1: First go at this

Existing Guideline

GConf XML schema registration

Currently, when a package requires an XML schema it is installed in %{_sysconfdir}/gconf/schemas/ (such as gcalctool in the following example), gconftool-2 should be run after the package is installed/uninstalled in FC4 or later. If the package is upgraded, the existing schema is deleted and removed from the XML schema tree (registry) and then the package provided schema is installed and registered. This is required so that the program(s) have a default configuration and for any custom options a user may wish to edit with using gconf-editor.

Note that this is required for any package that uses GConf for its configuration that must register its configurations into the registry.


%find_lang gcalctool --with-gnome

%post
scrollkeeper-update -q
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
gconftool-2 --makefile-install-rule %{_sysconfdir}/gconf/schemas/gcalctool.schemas >  /dev/null || :

%pre
if [ "$1" -gt 1 ]; then
  export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
  gconftool-2 --makefile-uninstall-rule %{_sysconfdir}/gconf/schemas/gcalctool.schemas > /dev/null || :
fi

%preun
if [ "$1" -eq 0 ]; then
  export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
  gconftool-2 --makefile-uninstall-rule %{_sysconfdir}/gconf/schemas/gcalctool.schemas > /dev/null || :
fi

Proposal

Motivations for changing the existing guideline:

  • Speed up package install/upgrade. Right now it is painful when preforming Anaconda installs and yum updates for new packages, it takes a long time for the XML schemas to register and this is done for each GConf related package and each sub-package as well.
  • gconftool-2 currently runs on every package install/upgrade, which is very inefficient. When preforming an upgrade of a package using the existing guidelines, there is no comparing of the existing schema and this needlessly removes and re-registers with an unchanged schema, slowing down Anaconda installs and yum updates.

New GConf registration

Using OpenSuSE's existing macros.gconf2 with minor modifications (as needed) we can dramatically improve install and upgrade times for our users. Upgrading existing RPMs will have their schemas compared and if they are the same, no changes are done to the user's system configuration registry. If there are changes, then the schema is registered as normal within %posttrans section.

Since schema registrations are usually not dependant on other packages being installed (and probably should not be) we are able to push these registrations to a %posttrans section.

Typical example of how the new macros work:

Name: gcalctool
...
...
...
Requires(post): GConf2
...
%gconf_schemas_prereq  [This basically is just Requires(pre): GConf2 coreutils diffutils ]

%install 
...
# Find GConf XML Schemas
%find_gconf_schemas

%find_lang gcalctool --with-gnome
cat %{name}.schemas_list %{name}.lang >%{name}.lst

%pre -f %{name}.schemas_pre

%preun -f %{name}.schemas_preun

%posttrans -f %{name}.schemas_posttrans

#%files -f gcalctool.lang
%files -f %{names}.lst
#%{_sysconfdir}/gconf/schemas/gcalctool.schemas


  • rpm-scriptlets are generated by the macros in %pre, %preun, %posttrans
  • We do not need to explicitly include the schema files in the %file section.

Description of new GConf macros

The following macros are available:

gconf_schemas_prereq - This macro just looks for some pre-requirements.
find_gconf_schemas - Searches the package during build time in $RPM_BUILD_ROOT/etc/gconf/schemas and builds a list of them and creates rpm-scriptlets in the process for each schema file found.
def_gconf_schemas - Define a schema, set file permissions for use with %file section, create %pre, %preun, %posttrans rpm-scriptlets.
add_gconf_schemas - Creates %pre section setup up comparing existing schema with new one, creates uninstall scriptlet for %preun section to remove schema from registry.
end_gconf_schemas> - You must call this macro if you do not use the find_gconf_schemas macro. This macro does a compare list against schemas that need to be registered in a %posttrans scriptlet and which ones need to be uninstalled in a %preun scriptlet.


The Macro file macro.gconf2 (slightly modified)

#                                                                           
# RPM macros for gconf applications.                                        
#                                                                           
# (c) 2006-2007 SUSE LINUX                                                  
# Author: Stanislav Brabec <sbrabec@suse.cz>                                
#                                                                           
# Usage:                                                                    
#                                                                           
# Preamble:                                                                 
# %gconf_schemas_prereq                                                     
#                                                                           
# %install                                                                  
# ...                                                                       
# %find_gconf_schemas                                                       
# or                                                                        
# %def_gconf_schemas subpackage1                                            
# %add_gconf_schemas schemas_name1                                          
# %add_gconf_schemas schemas_name2                                          
# %def_gconf_schemas subpackage2                                            
# %add_gconf_schemas schemas_name3                                          
# %add_gconf_schemas schemas_name4                                          
# %end_gconf_schemas                                                        
# schemas names are without path and suffix                                 
#                                                                           
# %pre -f %{name}.schemas_pre                                               
#                                                                           
# %preun -f %{name}.schemas_preun                                           
#                                                                           
# %posttrans -f %{name}.schemas_posttrans                                   
#                                                                           
# %files -f %{name}.schemas_list                                            
# or                                                                        
# %files -f subpackage.schemas_list                                         
#                                                                           
#                                                                           
# In case of more -f needed for one %files:                                 
#                                                                           
# %install                                                                  
# ...                                                                       
# %find_gconf_schemas                                                       
# %find_lang %{name}                                                        
# cat %{name}.schemas_list %{name}.lang >%{name}.lst                        
#                                                                           
# %files -f %{name}.lst                                                     
#                                                                           

%gconf_schemas_prereq PreReq: /usr/bin/gconftool-2 coreutils diffutils

%end_gconf_schemas() \
echo 'if test "x$UNINSTALL_SCHEMA_FILES" != "x"; then\
    usr/bin/gconftool-2 --makefile-uninstall-rule $UNINSTALL_SCHEMA_FILES >/dev/null\
    rm -f $UNINSTALL_SCHEMA_FILES\                                                   
fi\                                                                                  
if test "x$INSTALL_SCHEMA_FILES" != "x"; then\                                       
    usr/bin/gconftool-2 --makefile-install-rule $INSTALL_SCHEMA_FILES >/dev/null\    
fi\                                                                                  
rmdir etc/gconf/schemas/outdated 2>/dev/null || true' >>$GCONF_SCHEMAS_NAME.schemas_posttrans\
echo '    rmdir etc/gconf/schemas/outdated 2>/dev/null || true\                               
fi' >>$GCONF_SCHEMAS_NAME.schemas_preun\                                                      
%{nil}                                                                                        

%def_gconf_schemas() \
if test -n "$GCONF_SCHEMAS_NAME" ; then\
    %end_gconf_schemas\                 
fi\                                     
GCONF_SCHEMAS_NAME=%1\                  
echo '%defattr (644, root, root, 755)' >%1.schemas_list\
echo 'mkdir -p etc/gconf/schemas/outdated' >%1.schemas_pre\
echo 'export GCONF_CONFIG_SOURCE=`usr/bin/gconftool-2 --get-default-source`\
INSTALL_SCHEMA_FILES=\                                                      
UNINSTALL_SCHEMA_FILES=' >%1.schemas_posttrans\                             
echo 'if test "$1" == "0"; then\                                            
    if test -x usr/bin/gconftool-2 ; then\                                  
        export GCONF_CONFIG_SOURCE=`usr/bin/gconftool-2 --get-default-source`\
    fi' >%1.schemas_preun\                                                    
%{nil}                                                                        

%_add_gconf_schemas() \
echo $SCHEMAS >>$GCONF_SCHEMAS_NAME.schemas_list\
echo "if test -f ${SCHEMAS#/} ; then\            
    ln -f ${SCHEMAS#/} etc/gconf/schemas/outdated/\
fi" >>$GCONF_SCHEMAS_NAME.schemas_pre\             
echo "if test -f etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/}; then\
    cmp --quiet etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/} ${SCHEMAS#/}\
    if test \\\$? != 0; then\                                                          
        UNINSTALL_SCHEMA_FILES=\\\"\\\$UNINSTALL_SCHEMA_FILES etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/}\\\"\                                                                            
        INSTALL_SCHEMA_FILES=\\\"\\\$INSTALL_SCHEMA_FILES ${SCHEMAS#/}\\\"\                         
    else\                                                                                           
        rm -f etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/}\
    fi\
else\
  INSTALL_SCHEMA_FILES=\\\"\\\$INSTALL_SCHEMA_FILES ${SCHEMAS#/}\\\"\
fi" >>$GCONF_SCHEMAS_NAME.schemas_posttrans\
echo "    if test -x usr/bin/gconftool-2 ; then\
        if test -f etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/} ; then\
            usr/bin/gconftool-2 --makefile-uninstall-rule etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/} >/dev/null\
        elif test -f ${SCHEMAS#/} ; then\
            usr/bin/gconftool-2 --makefile-uninstall-rule ${SCHEMAS#/} >/dev/null\
        fi\
    fi\
    rm -f etc/gconf/schemas/outdated/${SCHEMAS#/etc/gconf/schemas/}" >>$GCONF_SCHEMAS_NAME.schemas_preun\
%{nil}

%add_gconf_schemas() \
SCHEMAS=/etc/gconf/schemas/%1.schemas\
%_add_gconf_schemas\
%{nil}

%find_gconf_schemas() \
test -d $RPM_BUILD_ROOT/etc/gconf/schemas\
%def_gconf_schemas %{name}\
for SCHEMAS in $RPM_BUILD_ROOT/etc/gconf/schemas/*.schemas ; do\
    test -f $SCHEMAS\
    SCHEMAS=${SCHEMAS#$RPM_BUILD_ROOT}\
    %_add_gconf_schemas\
done\
%end_gconf_schemas\
%{nil}