Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add podman-based development support #84

Merged
merged 7 commits into from
Feb 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ docs/sphinxdocs/_build
.project
.pydevproject
asthelper.completions
build
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# YUM development image

FROM centos:7

# Set up EPEL
RUN yum install -y \
epel-release

# Install useful stuff
RUN yum install -y \
python-pip \
python-ipdb \
ipython \
vim \
less
RUN rpm -e --nodeps yum
RUN rm -rf /var/cache/yum
RUN pip install --upgrade pip && pip install pudb

# Use the yum checkout mounted from the host
ENV PATH=/src/bin:$PATH \
PYTHONPATH=/src:$PYTHONPATH
RUN ln -s /src/etc/yum.conf /etc/yum.conf
RUN ln -s /src/etc/version-groups.conf /etc/yum/version-groups.conf

VOLUME ["/src"]
ENTRYPOINT ["/bin/bash"]
40 changes: 36 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ PYTHON=python
WEBHOST = yum.baseurl.org
WEB_DOC_PATH = /srv/projects/yum/web/download/docs/yum-api/

BUILDDIR = build
MOCK_CONF = epel-7-x86_64
PODMAN_IMAGE = yum-devel

all: subdirs

clean:
rm -f *.pyc *.pyo *~ *.bak
rm -f $(BUILDDIR)/{SOURCES,SRPMS,RPMS}/*
mock -r $(MOCK_CONF) --clean
for d in $(SUBDIRS); do make -C $$d clean ; done
cd test; rm -f *.pyc *.pyo *~ *.bak

Expand All @@ -31,7 +37,7 @@ install:
$(PYTHON) -c "import compileall; compileall.compile_dir('$(DESTDIR)/usr/share/yum-cli', 1, '/usr/share/yum-cli', 1)"

mkdir -p $(DESTDIR)/usr/bin $(DESTDIR)/usr/sbin
install -m 755 bin/yum.py $(DESTDIR)/usr/bin/yum
install -m 755 bin/yum $(DESTDIR)/usr/bin/yum
install -m 755 bin/yum-updatesd.py $(DESTDIR)/usr/sbin/yum-updatesd

mkdir -p $(DESTDIR)/var/cache/yum
Expand All @@ -58,7 +64,7 @@ transifex:
make transifex-push
git commit -a -m 'Transifex push, yum.pot update'

.PHONY: docs test
.PHONY: docs test srpm rpm shell

DOCS = yum rpmUtils callback.py yumcommands.py shell.py output.py cli.py utils.py\
yummain.py
Expand Down Expand Up @@ -113,12 +119,38 @@ _archive:
@rm -rf ${PKGNAME}-%{VERSION}.tar.gz
@rm -rf /tmp/${PKGNAME}-$(VERSION) /tmp/${PKGNAME}
@dir=$$PWD; cd /tmp; git clone $$dir ${PKGNAME}
lynx -dump 'http:https://yum.baseurl.org/wiki/WritingYumPlugins?format=txt' > /tmp/${PKGNAME}/PLUGINS
lynx -dump 'http:https://yum.baseurl.org/wiki/Faq?format=txt' > /tmp/${PKGNAME}/FAQ
@touch /tmp/${PKGNAME}/PLUGINS
@touch /tmp/${PKGNAME}/FAQ
@rm -f /tmp/${PKGNAME}/$(remove_spec)
@rm -rf /tmp/${PKGNAME}/.git
@mv /tmp/${PKGNAME} /tmp/${PKGNAME}-$(VERSION)
@dir=$$PWD; cd /tmp; tar cvzf $$dir/${PKGNAME}-$(VERSION).tar.gz ${PKGNAME}-$(VERSION)
@rm -rf /tmp/${PKGNAME}-$(VERSION)
@echo "The archive is in ${PKGNAME}-$(VERSION).tar.gz"

### RPM packaging ###

$(BUILDDIR):
@mkdir -p $@/{SOURCES,SRPMS,RPMS}

srpm: archive $(BUILDDIR)
@cp $(PKGNAME)-$(VERSION).tar.gz $(BUILDDIR)/SOURCES/
@rpmbuild --define '_topdir $(BUILDDIR)' -bs yum.spec

rpm: srpm
@mock -r $(MOCK_CONF) --resultdir=$(BUILDDIR)/RPMS \
--no-clean --no-cleanup-after \
$(BUILDDIR)/SRPMS/$(PKGNAME)-$(VERSION)-$(RELEASE).src.rpm
@echo "The RPMs are in $(BUILDDIR)/RPMS"

### Container-based development ###

$(BUILDDIR)/image: Dockerfile $(BUILDDIR)
podman build -t $(PODMAN_IMAGE) .
@touch $@

shell: $(BUILDDIR)/image
@podman run \
-v=$(CURDIR):/src:ro,z \
--detach-keys="ctrl-@" \
-it $(PODMAN_ARGS) $(PODMAN_IMAGE) || true
35 changes: 0 additions & 35 deletions README

This file was deleted.

76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# YUM

Yum is an automatic updater and installer for rpm-based systems.

Included programs:

/usr/bin/yum Main program

## Usage

Yum is run with one of the following options:

* `update [package list]`

If run without any packages, Yum will automatically upgrade every currently
installed package. If one or more packages are specified, Yum will only
update the packages listed.

* `install <package list>`

Yum will install the latest version of the specified package (don't specify
version information).

* `remove <package list>`

Yum will remove the specified packages from the system.

* `list [package list]`

List available packages.

See the man page for more information (`man yum`). Also see:

* web page: http:https://yum.baseurl.org/

* wiki: http:https://yum.baseurl.org/wiki

```
3.2.X Branch - yum-3_2_X
Starting commit is roughly: a3c91d7f6a15f31a42d020127b2da2877dfc137d
E.g. git diff a3c91d7f6a15f31a42d020127b2da2877dfc137d
```

## Building

You can build an RPM package by running:

$ make rpm

**Note:** Make sure you have `mock` and `lynx` installed.

## Development

You can run Yum from the current checkout in a container as follows (make sure
you have the `podman` package installed):

$ make shell

This will first build a CentOS 7 image (if not built already) and then run a
container with a shell where you can directly execute Yum:

[root@bf03d3a43cbf /] yum

When you edit the code on your host, the changes you make will be immediately
reflected inside the container since the checkout is bind-mounted.

**Warning:** There's a (probably) bug in podman at the moment which makes it
not see symlinks in a freshly created container, which, in turn, makes Yum not
see the `/etc/yum.conf` symlink when it runs for the first time. The
workaround is to `touch /etc/yum.conf` or simply re-run Yum.

**Note:** When you exit the container, it is not deleted but just stopped. To
re-attach to it, use (replace the ID appropriately):

$ podman start bf03d3a43cbf
$ podman attach bf03d3a43cbf
File renamed without changes.
6 changes: 5 additions & 1 deletion test/pubringtests.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import unittest
import gpg
import os
import shutil
import tempfile
import time

from yum import misc
from yum.misc import gpg

PWD = os.path.dirname(os.path.abspath(__file__))
KEYDIR = '%s/gpg' % PWD
Expand All @@ -26,6 +26,10 @@ def setUp(self):
self.ctx = gpg.Context()

def tearDown(self):
if isinstance(gpg, misc.GpgmeAdapter):
shutil.rmtree(self.gpgdir)
return

# Ask gpg-agent to quit (copied from the gpgme test suite). If we
# didn't do this, shutil.rmtree() could fail when deleting some of the
# sockets due to them already being gone. That's because gpg-agent
Expand Down
12 changes: 8 additions & 4 deletions yum.spec
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,20 @@ BuildRequires: rpm-python, rpm >= 0:4.4.2
BuildRequires: python-iniparse
BuildRequires: python-urlgrabber >= 3.10-8
BuildRequires: yum-metadata-parser >= 1.1.0
%if 0%{?rhel}
BuildRequires: pygpgme
Requires: pygpgme
%else
BuildRequires: python2-gpg
Requires: python2-gpg
%endif
# End of CheckRequires
Conflicts: pirut < 1.1.4
Requires: python >= 2.4
Requires: rpm-python, rpm >= 0:4.4.2
Requires: python-iniparse
Requires: python-urlgrabber >= 3.10-8
Requires: yum-metadata-parser >= 1.1.0
Requires: python2-gpg
# rawhide is >= 0.5.3-7.fc18 ... as this is added.
Requires: pyliblzma
# Not really a suggests anymore, due to metadata using it.
Expand Down Expand Up @@ -252,14 +257,13 @@ INIT=sysv

make DESTDIR=$RPM_BUILD_ROOT UNITDIR=%{_unitdir} INIT=$INIT install

install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/yum.conf
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d $RPM_BUILD_ROOT/%{yum_pluginslib}
mkdir -p $RPM_BUILD_ROOT/%{yum_pluginsshare}

%if %{move_yum_conf_back}
# for now, move repodir/yum.conf back
mv $RPM_BUILD_ROOT/%{_sysconfdir}/yum/repos.d $RPM_BUILD_ROOT/%{_sysconfdir}/yum.repos.d
rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/yum/yum.conf
mv $RPM_BUILD_ROOT/%{_sysconfdir}/yum/yum.conf $RPM_BUILD_ROOT/%{_sysconfdir}/yum.conf
%endif

%if %{yum_updatesd}
Expand Down Expand Up @@ -406,7 +410,7 @@ exit 0

%files -f %{name}.lang
%defattr(-, root, root, -)
%doc README AUTHORS COPYING TODO ChangeLog PLUGINS docs/comps.rng
%doc README.md AUTHORS COPYING TODO ChangeLog PLUGINS docs/comps.rng
%if %{move_yum_conf_back}
%config(noreplace) %{_sysconfdir}/yum.conf
%dir %{_sysconfdir}/yum.repos.d
Expand Down
57 changes: 56 additions & 1 deletion yum/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import pgpmsg
import tempfile
import glob
import gpg
import pwd
import fnmatch
import bz2
Expand All @@ -36,6 +35,62 @@

from rpmUtils.miscutils import stringToVersion, flagToString
from stat import *

class GpgmeAdapter(object):
"""Wrapper for the old gpg API."""

class errors(object):
class GPGMEError(Exception):
pass
class BadSignatures(Exception):
pass

class Context(object):
def __init__(self):
self.ctx = gpgme.Context()

def __enter__(self):
return self

def __exit__(self, *args):
pass

def op_import(self, rawkey):
keyf = StringIO(rawkey)
imp = self.ctx.import_(keyf)
keyf.close()
# Ultimately trust the key
fpr = imp.imports[0][0]
key = self.ctx.get_key(fpr)
gpgme.editutil.edit_trust(self.ctx, key, gpgme.VALIDITY_ULTIMATE)

def verify(self, signed_text, sig, plaintext):
try:
sigs = self.ctx.verify(sig, signed_text, plaintext)
except gpgme.GpgmeError as e:
raise GpgmeAdapter.errors.GPGMEError()
# is there ever a case where we care about a sig beyond the first
# one?
if not sigs or not sigs[0] or sigs[0].validity not in (
gpgme.VALIDITY_FULL, gpgme.VALIDITY_MARGINAL,
gpgme.VALIDITY_ULTIMATE):
raise GpgmeAdapter.errors.BadSignatures()

def __getattr__(self, name):
return getattr(self.ctx, name)

def __getattr__(self, name):
return getattr(gpgme, name)

try:
# Official GnuPG Python binding (not available on CentOS/RHEL <= 7)
import gpg
except ImportError:
# Alternative fallback implementation (not available on Fedora any more)
import gpgme
import gpgme.editutil
gpg = GpgmeAdapter()

try:
import hashlib
_available_checksums = set(['md5', 'sha1', 'sha256', 'sha384', 'sha512'])
Expand Down