epm-repack 9.65 KB
Newer Older
1 2
#!/bin/sh
#
3 4
# Copyright (C) 2017-2018, 2020  Etersoft
# Copyright (C) 2017-2018, 2020  Vitaly Lipatov <lav@etersoft.ru>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

load_helper epm-sh-altlinux
load_helper epm-assure

23 24 25
# arg: rpm or deb
# fills split_replaced_pkgs with packages of that type
__epm_split_by_pkg_type()
26
{
27 28 29 30 31 32 33
	local type="$1"
	shift

	split_replaced_pkgs=''

	for pkg in "$@" ; do
		[ "$(get_package_type "$pkg")" = "$type" ] || return 1
34
		[ -e "$pkg" ] || fatal "Can't read $pkg"
35
		split_replaced_pkgs="$split_target_pkgs $(realpath "$pkg")"
36
	done
37 38 39 40 41 42

	[ -n "$split_replaced_pkgs" ]
}

# fills repacked_debs
__epm_repack_rpm_to_deb()
43 44 45 46 47 48 49
{
	local pkg

	assure_exists alien
	assure_exists fakeroot
	assure_exists rpm

50 51
	repacked_debs=''

52 53
	local TDIR=$(mktemp -d)
	cd $TDIR || fatal
54

55 56 57
	for pkg in $rpmpkgs ; do
		showcmd_store_output fakeroot alien -d -k $scripts "$pkg"
		local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g")
58 59
		repacked_debs="$repacked_rpms $(realpath $DEBCONVERTED)"
		to_remove_pkg_files="$to_remove_pkg_files $(realpath $DEBCONVERTED)"
60 61
		clean_store_output
	done
62

63 64 65 66 67 68 69 70
	# TODO: move it to exit handler
	if [ -z "$DEBUG" ] ; then
		# TODO: reinvent
		[ -n "$to_remove_pkg_files" ] && rm -f $to_remove_pkg_files
		[ -n "$to_remove_pkg_files" ] && rmdir $(dirname $to_remove_pkg_files | head -n1) 2>/dev/null
		[ -n "$to_remove_pkg_dirs" ] && rmdir $to_remove_pkg_dirs
	fi

71 72 73 74 75 76 77 78 79
	cd - >/dev/null
	return 0
}


# TODO: rewrite to convert (get some code from Korinf?)
__epm_check_if_try_install_rpm()
{
	__epm_split_by_pkg_type rpm "$@" || return 1
80
	__epm_repack_rpm_to_deb $split_replaced_pkgs
81 82 83

	# TODO: move to install
	docmd epm install $force $nodeps $repacked_debs
84 85 86 87 88 89 90 91 92 93

	return 0
}


# args: buildroot spec
__fix_spec()
{
    local buildroot="$1"
    local spec="$2"
94
    local pkgname="$3"
95
    local i
96 97 98

    # drop forbidded paths
    # https://bugzilla.altlinux.org/show_bug.cgi?id=38842
99
    for i in / /etc /etc/init.d /etc/systemd /bin /opt /usr /usr/bin /usr/share /usr/share/doc /var /var/log /var/run \
100
            /etc/cron.daily /usr/share/icons /usr/share/pixmaps /usr/share/man /usr/share/man/man1 /usr/share/appdata /usr/share/applications /usr/share/menu ; do
101 102 103 104 105 106
        sed -i -e "s|^%dir \"$i/*\"$||" \
            -e "s|^\"$i/*\"$||" \
            -e "s|^$i/*$||" \
            $spec
    done

107 108 109 110 111 112
    # drop %dir for existed system dirs
    for i in $(grep '^%dir "' $spec | sed -e 's|^%dir  *"\(.*\)".*|\1|' ) ; do #"
        echo "$i" | grep -q '^/opt/' && continue
        [ -d "$i" ] && echo "drop dir $i from packing, it exists in the system"
    done

113
    # replace dir "/path/dir" -> %dir /path/dir
114
    grep '^"/' $spec | sed -e 's|^"\(/.*\)"$|\1|' | while read i ; do
115
        # add dir as %dir in the filelist
116 117
        if [ -d "$buildroot$i" ] ; then
            subst 's|^\("'$i'"\)$|%dir \1|' $spec
118 119
        #else
        #    subst 's|^\("'$i'"\)$|\1|' $spec
120 121
        fi
    done
122 123 124

    # FIXME: where is a source of the bug with empty Summary?
    subst "s|Summary: *$|Summary: $pkgname (was empty Summary after alien)|" $spec
125
    subst "s|^Release: |Release: alt1.repacked.with.epm.|" $spec
126
    subst "s|^\((Converted from a\) \(.*\) \(package.*\)|(Repacked from binary \2 package with epm $EPMVERSION)\n\1 \2 \3|" $spec
127 128 129
    #" hack for highlight
}

130 131 132 133 134 135 136 137 138 139 140 141 142
# TODO: move this list from external file
__check_stoplist()
{
    cat <<EOF | grep -q "^$1$"
kesl
kesl-astra
klnagent
klnagent64
klnagent64-astra
EOF
}


143 144
__apply_fix_code()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
145
    local repackcode="$CONFIGDIR/repack.d/$1.sh"
146 147
    [ -x "$repackcode" ] || return
    shift
148
    export PATH=$PROGDIR:$PATH
149
    docmd $repackcode "$1" "$2" || fatal "There is an error from $repackcode script"
150 151
}

152 153 154 155 156 157 158 159 160
__create_rpmmacros()
{
    cat <<EOF >$HOME/.rpmmacros
%_topdir	$HOME/RPM
%_tmppath	$TMPDIR

%packager	EPM <support@etersoft.ru>
%_gpg_name	support@etersoft.ru
EOF
161
    to_remove_pkg_files="$to_remove_pkg_files $HOME/.rpmmacros"
162 163
}

164
# will fill repacked_rpms var
Vitaly Lipatov's avatar
Vitaly Lipatov committed
165
__epm_repack_to_rpm()
166
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
167
    local pkgs="$*"
168 169
    assure_distr ALTLinux "install --repack"

Vitaly Lipatov's avatar
Vitaly Lipatov committed
170
    # install epm-repack for static (package based) dependencies
171 172 173 174
    assure_exists fakeroot || fatal
    assure_exists alien || fatal
    assure_exists rpmbuild rpm-build || fatal

175
    # TODO: improve
Vitaly Lipatov's avatar
Vitaly Lipatov committed
176
    if echo "$pkgs" | grep "\.deb" ; then
177 178 179 180 181
        assure_exists dpkg || fatal
        # TODO: Для установки требует: /usr/share/debconf/confmodule но пакет не может быть установлен
        # assure_exists debconf
    fi

182
    local pkg
183 184
    export HOME=$(mktemp -d)
    __create_rpmmacros
185

186
    local alpkg
187
    local abspkg
Vitaly Lipatov's avatar
Vitaly Lipatov committed
188
    local tmpbuilddir
189
    repacked_rpms=''
Vitaly Lipatov's avatar
Vitaly Lipatov committed
190 191
    for pkg in $pkgs ; do
        tmpbuilddir=$HOME/$(basename $pkg).tmpdir
192
        mkdir $tmpbuilddir
193
        abspkg="$(realpath $pkg)"
194
        info ""
195
        info "Repacking $abspkg to local rpm format ..."
196 197 198
        # alien failed with spaced names
        # alpkg=$abspkg
        alpkg=$(basename $pkg)
199 200 201 202
        # TODO: use func for get name from deb pkg
        # TODO: epm print name from deb package
        # TODO: use stoplist only for deb?
        [ -z "$force" ] && __check_stoplist $(echo $alpkg | sed -e "s|_.*||") && fatal "Please use official rpm package instead of $alpkg (It is not recommended to use --force to skip this checking."
203
        # don't use abs package path: copy package to temp dir and use there
204
        cp -v $pkg $tmpbuilddir/../$alpkg
205
        cd $tmpbuilddir || fatal
206
        docmd fakeroot alien --generate --to-rpm $verbose $scripts "../$alpkg" || fatal
207 208 209 210 211 212 213 214 215 216

        local subdir="$(echo *)"
        [ -d "$subdir" ] || fatal "can't find subdir"

        # detect spec and move to prev dir
        local spec="$(echo $tmpbuilddir/$subdir/*.spec)"
        [ -s "$spec" ] || fatal "can't find spec"
        mv $spec $tmpbuilddir || fatal
        spec="$tmpbuilddir/$(basename "$spec")"
        local pkgname="$(grep "^Name: " $spec | sed -e "s|Name: ||g" | head -n1)"
217
        __fix_spec $tmpbuilddir/$subdir $spec $pkgname
218
        __apply_fix_code $pkgname $tmpbuilddir/$subdir $spec
219 220
        # TODO: we need these dirs to be created
        to_remove_pkg_dirs="$to_remove_pkg_dirs $HOME/RPM/BUILD $HOME/RPM"
221 222
        showcmd fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir --define='_allow_root_build 1' -bb $spec
        if [ -n "$verbose" ] ; then
223
            a='' fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir  --define='_allow_root_build 1' -bb $spec || fatal
224
        else
225
            a='' fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir  --define='_allow_root_build 1' -bb $spec >/dev/null || fatal
226
        fi
227 228 229
        # remove copy of source binary package (don't mix with generated)
        rm -f $tmpbuilddir/../$alpkg
        local repacked_rpm="$(realpath $tmpbuilddir/../*.rpm)"
230 231 232 233
        if [ -s "$repacked_rpm" ] ; then
            repacked_rpms="$repacked_rpms $repacked_rpm"
            to_remove_pkg_files="$to_remove_pkg_files $repacked_rpm"
        else
234
            warning "Can't find converted rpm for source binary package '$pkg'"
235 236 237 238 239
        fi
        cd - >/dev/null
        rm -rf $tmpbuilddir/$subdir/
        rm -rf $spec
    done
240 241

    to_remove_pkg_dirs="$to_remove_pkg_dirs $HOME"
242 243 244 245 246
    rmdir $tmpbuilddir
    #rmdir $tmpbuilddir/..
    true
}

247 248 249
__epm_check_if_try_install_deb()
{
	__epm_split_by_pkg_type deb "$@" || return 1
Vitaly Lipatov's avatar
Vitaly Lipatov committed
250
	__epm_repack_to_rpm $split_replaced_pkgs || fatal
251 252 253 254

	# TODO: move to install
	docmd epm install $force $nodeps $repacked_rpms

255 256 257 258 259 260 261 262
	# TODO: move it to exit handler
	if [ -z "$DEBUG" ] ; then
		# TODO: reinvent
		[ -n "$to_remove_pkg_files" ] && rm -f $to_remove_pkg_files
		[ -n "$to_remove_pkg_files" ] && rmdir $(dirname $to_remove_pkg_files | head -n1) 2>/dev/null
		[ -n "$to_remove_pkg_dirs" ] && rmdir $to_remove_pkg_dirs 2>/dev/null
	fi

263 264 265 266
	return 0
}


267 268 269 270 271 272 273 274
epm_repack()
{
    # if possible, it will put pkg_urls into pkg_files and reconstruct pkg_filenames
    if [ -n "$pkg_urls" ] ; then
        load_helper epm-download
        __handle_pkg_urls_to_install
    fi

275
    [ -n "$pkg_names" ] && warning "Can't find $pkg_names"
276 277
    [ -z "$pkg_files" ] && info "Skip empty repack list" && return 22

278 279
    case $PKGFORMAT in
        rpm)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
280
            __epm_repack_to_rpm $pkg_files || fatal
281 282 283 284 285 286
            echo
            echo "Adapted packages:"
            cp $repacked_rpms .
            for i in $repacked_rpms ; do
                echo "	$(pwd)/$(basename "$i")"
            done
287 288 289 290 291 292
            ;;
        deb)
            if __epm_split_by_pkg_type rpm $pkg_files ; then
                __epm_repack_rpm_to_deb $split_replaced_pkgs
                cp -v $repacked_debs .
                pkg_files="$(estrlist exclude $split_replaced_pkgs $pkg_files)"
293
                [ -n "$pkg_files" ] && warning "There are left unconverted packages $pkg_files."
294 295 296 297 298 299 300
            fi
            ;;
        *)
            fatal "$PKGFORMAT is not supported for repack yet"
            ;;
    esac

301 302
    # TODO: move it to exit handler
    if [ -z "$DEBUG" ] ; then
303 304 305 306 307
        # TODO: reinvent
        [ -n "$to_remove_pkg_files" ] && rm -f $to_remove_pkg_files
        # hack??
        [ -n "$to_remove_pkg_files" ] && rmdir $(dirname $to_remove_pkg_files | head -n1) 2>/dev/null
        [ -n "$to_remove_pkg_dirs" ] && rmdir $to_remove_pkg_dirs 2>/dev/null
308 309 310
    fi

}