From ab4cfb5e84a95decd06487dc4e59827ddb8ce79d Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Wed, 10 Nov 2021 19:50:35 +0000
Subject: [PATCH] replace deprecated distutils with setuptools

Adds python3 setuptools as a build dependency for libapparmor

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/202
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/813
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
(cherry picked from commit 21e5a721ab2abe26bb12b9da7accc39d4fff9804)
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
 .gitignore                                    |  3 ++
 .gitlab-ci.yml                                |  2 +-
 libraries/libapparmor/m4/ac_python_devel.m4   | 36 +++++++++----------
 libraries/libapparmor/swig/python/Makefile.am |  2 +-
 libraries/libapparmor/swig/python/setup.py.in |  2 +-
 .../libapparmor/swig/python/test/Makefile.am  |  2 +-
 profiles/Makefile                             |  2 +-
 utils/Makefile                                |  1 +
 utils/python-tools-setup.py                   |  6 ++--
 utils/test/Makefile                           |  2 +-
 utils/test/README.md                          | 18 ++++++++++
 11 files changed, 49 insertions(+), 27 deletions(-)
 create mode 100644 utils/test/README.md

--- a/.gitignore
+++ b/.gitignore
@@ -159,6 +159,7 @@ libraries/libapparmor/swig/perl/libappar
 libraries/libapparmor/swig/perl/libapparmor_wrap.o
 libraries/libapparmor/swig/perl/pm_to_blib
 libraries/libapparmor/swig/python/LibAppArmor.py
+libraries/libapparmor/swig/python/LibAppArmor.egg-info/
 libraries/libapparmor/swig/python/build/
 libraries/libapparmor/swig/python/libapparmor_wrap.c
 libraries/libapparmor/swig/python/Makefile
@@ -203,6 +204,8 @@ utils/*.tmp
 utils/po/*.mo
 utils/apparmor/*.pyc
 utils/apparmor/rule/*.pyc
+utils/apparmor.egg-info/
+utils/build/
 utils/htmlcov/
 utils/test/common_test.pyc
 utils/test/.coverage
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
 ---
 image: ubuntu:latest
 before_script:
-  - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install --no-install-recommends -y build-essential apache2-dev autoconf automake bison dejagnu flex libpam-dev libtool perl liblocale-gettext-perl pkg-config python-all-dev python3-all-dev pyflakes3 ruby-dev swig lsb-release python3-notify2 python3-psutil zlib1g-dev
+  - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install --no-install-recommends -y build-essential apache2-dev autoconf automake bison dejagnu flex libpam-dev libtool perl liblocale-gettext-perl pkg-config python-all-dev python3-all-dev pyflakes3 ruby-dev swig lsb-release python3-notify2 python3-psutil python3-setuptools zlib1g-dev
   - lsb_release -a
   - uname -a
 
--- a/libraries/libapparmor/m4/ac_python_devel.m4
+++ b/libraries/libapparmor/m4/ac_python_devel.m4
@@ -66,17 +66,17 @@ variable to configure. See ``configure -
         fi
 
         #
-        # Check if you have distutils, else fail
+        # Check if you have setuptools, else fail
         #
-        AC_MSG_CHECKING([for the distutils Python package])
-        ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
-        if test -z "$ac_distutils_result"; then
+        AC_MSG_CHECKING([for the setuptools Python package])
+        ac_setuptools_result=`$PYTHON -c "import setuptools" 2>&1`
+        if test -z "$ac_setuptools_result"; then
                 AC_MSG_RESULT([yes])
         else
                 AC_MSG_RESULT([no])
-                AC_MSG_ERROR([cannot import Python module "distutils".
+                AC_MSG_ERROR([cannot import Python module "setuptools".
 Please check your Python installation. The error was:
-$ac_distutils_result])
+$ac_setuptools_result])
                 PYTHON_VERSION=""
         fi
 
@@ -88,8 +88,8 @@ $ac_distutils_result])
                 PYTHON_CPPFLAGS=`$PYTHON_CONFIG --includes`
         fi
         if test -z "$PYTHON_CPPFLAGS"; then
-                python_path=`$PYTHON -c "import sys; import distutils.sysconfig;\
-sys.stdout.write('%s\n' % distutils.sysconfig.get_python_inc());"`
+                python_path=`$PYTHON -c "import sys; import sysconfig;\
+sys.stdout.write('%s\n' % sysconfig.get_path('include'));"`
                 if test -n "${python_path}"; then
                         python_path="-I$python_path"
                 fi
@@ -108,8 +108,8 @@ sys.stdout.write('%s\n' % distutils.sysc
         if test -z "$PYTHON_LDFLAGS"; then
                 # (makes two attempts to ensure we've got a version number
                 # from the interpreter)
-                py_version=`$PYTHON -c "import sys; from distutils.sysconfig import *; \
-sys.stdout.write('%s\n' % ''.join(get_config_vars('VERSION')))"`
+                py_version=`$PYTHON -c "import sys; import sysconfig; \
+sys.stdout.write('%s\n' % ''.join(sysconfig.get_config_vars('VERSION')))"`
                 if test "$py_version" == "[None]"; then
                         if test -n "$PYTHON_VERSION"; then
                                 py_version=$PYTHON_VERSION
@@ -119,8 +119,8 @@ sys.stdout.write("%s\n" % sys.version[[:
                         fi
                 fi
 
-                PYTHON_LDFLAGS=`$PYTHON -c "import sys; from distutils.sysconfig import *; \
-sys.stdout.write('-L' + get_python_lib(0,1) + ' -lpython\n')"`$py_version`$PYTHON -c \
+                PYTHON_LDFLAGS=`$PYTHON -c "import sys; import sysconfig; \
+sys.stdout.write('-L' + sysconfig.get_path('stdlib') + ' -lpython\n')"`$py_version`$PYTHON -c \
 "import sys; sys.stdout.write('%s' % getattr(sys,'abiflags',''))"`
         fi
         AC_MSG_RESULT([$PYTHON_LDFLAGS])
@@ -131,8 +131,8 @@ sys.stdout.write('-L' + get_python_lib(0
         #
         AC_MSG_CHECKING([for Python site-packages path])
         if test -z "$PYTHON_SITE_PKG"; then
-                PYTHON_SITE_PKG=`$PYTHON -c "import sys; import distutils.sysconfig; \
-sys.stdout.write('%s\n' % distutils.sysconfig.get_python_lib(0,0));"`
+                PYTHON_SITE_PKG=`$PYTHON -c "import sys; import sysconfig; \
+sys.stdout.write('%s\n' % sysconfig.get_path('purelib'));"`
         fi
         AC_MSG_RESULT([$PYTHON_SITE_PKG])
         AC_SUBST([PYTHON_SITE_PKG])
@@ -146,8 +146,8 @@ sys.stdout.write('%s\n' % distutils.sysc
                         PYTHON_EXTRA_LIBS=''
         fi
         if test -z "$PYTHON_EXTRA_LIBS"; then
-           PYTHON_EXTRA_LIBS=`$PYTHON -c "import sys; import distutils.sysconfig; \
-conf = distutils.sysconfig.get_config_var; \
+           PYTHON_EXTRA_LIBS=`$PYTHON -c "import sys; import sysconfig; \
+conf = sysconfig.get_config_var; \
 sys.stdout.write('%s %s %s\n' % (conf('BLDLIBRARY'), conf('LOCALMODLIBS'), conf('LIBS')))"`
         fi
         AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
@@ -162,8 +162,8 @@ sys.stdout.write('%s %s %s\n' % (conf('B
                         PYTHON_EXTRA_LDFLAGS=''
         fi
         if test -z "$PYTHON_EXTRA_LDFLAGS"; then
-                PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sys; import distutils.sysconfig; \
-conf = distutils.sysconfig.get_config_var; \
+                PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sys; import sysconfig; \
+conf = sysconfig.get_config_var; \
 sys.stdout.write('%s\n' % conf('LINKFORSHARED'))"`
         fi
         AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
--- a/libraries/libapparmor/swig/python/Makefile.am
+++ b/libraries/libapparmor/swig/python/Makefile.am
@@ -21,7 +21,7 @@ install-exec-local:
 
 clean-local:
 	if test -x "$(PYTHON)"; then $(PYTHON) setup.py clean; fi
-	rm -rf build
+	rm -rf build LibAppArmor.egg-info
 	if test $(top_srcdir) != $(top_builddir) ; then rm -f libapparmor_wrap.c ; fi
 
 endif
--- a/libraries/libapparmor/swig/python/setup.py.in
+++ b/libraries/libapparmor/swig/python/setup.py.in
@@ -1,4 +1,4 @@
-from distutils.core import setup, Extension
+from setuptools import setup, Extension
 import string
 
 setup(name          = 'LibAppArmor',
--- a/libraries/libapparmor/swig/python/test/Makefile.am
+++ b/libraries/libapparmor/swig/python/test/Makefile.am
@@ -11,7 +11,7 @@ test_python.py: test_python.py.in $(top_
 CLEANFILES = test_python.py
 
 # bah, how brittle is this?
-PYTHON_DIST_BUILD_PATH = '$(builddir)/../build/$$($(PYTHON) -c "import distutils.util; import platform; print(\"lib.%s-%s\" %(distutils.util.get_platform(), platform.python_version()[:3]))")'
+PYTHON_DIST_BUILD_PATH = '$(builddir)/../build/$$($(PYTHON) -c "import sysconfig; print(\"lib.%s-%s\" %(sysconfig.get_platform(), sysconfig.get_python_version()))")'
 
 TESTS	= test_python.py
 TESTS_ENVIRONMENT = \
--- a/profiles/Makefile
+++ b/profiles/Makefile
@@ -41,7 +41,7 @@ ifdef USE_SYSTEM
     LOGPROF?=aa-logprof
 else
     # PYTHON_DIST_BUILD_PATH based on libapparmor/swig/python/test/Makefile.am
-    PYTHON_DIST_BUILD_PATH = ../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import distutils.util; import platform; print(\"lib.%s-%s\" %(distutils.util.get_platform(), platform.python_version()[:3]))")
+    PYTHON_DIST_BUILD_PATH = ../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import sysconfig; print(\"lib.%s-%s\" %(sysconfig.get_platform(), sysconfig.get_python_version()))")
     LIBAPPARMOR_PATH=../libraries/libapparmor/src/.libs/
     LD_LIBRARY_PATH=$(LIBAPPARMOR_PATH):$(PYTHON_DIST_BUILD_PATH)
     PYTHONPATH=../utils/:$(PYTHON_DIST_BUILD_PATH)
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -67,6 +67,7 @@ clean: pod_clean
 	rm -rf staging/ build/
 	rm -f apparmor/*.pyc apparmor/rule/*.pyc
 	rm -rf apparmor/__pycache__/ apparmor/rule/__pycache__/
+	rm -rf apparmor.egg-info/
 
 # ${CAPABILITIES} is defined in common/Make.rules
 .PHONY: check_severity_db
--- a/utils/python-tools-setup.py
+++ b/utils/python-tools-setup.py
@@ -20,14 +20,14 @@
 # Note: --version=... must be the last argument to this script
 #
 
-from distutils.command.install import install as _install
-from distutils.core import setup
+from setuptools.command.install import install as _install
+from setuptools import setup
 import os
 import shutil
 import sys
 
 class Install(_install, object):
-    '''Override distutils to install the files where we want them.'''
+    '''Override setuptools to install the files where we want them.'''
     def run(self):
         # Now byte-compile everything
         super(Install, self).run()
--- a/utils/test/Makefile
+++ b/utils/test/Makefile
@@ -28,7 +28,7 @@ ifdef USE_SYSTEM
     PARSER=
 else
     # PYTHON_DIST_BUILD_PATH based on libapparmor/swig/python/test/Makefile.am
-    PYTHON_DIST_BUILD_PATH = ../../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import distutils.util; import platform; print(\"lib.%s-%s\" %(distutils.util.get_platform(), platform.python_version()[:3]))")
+    PYTHON_DIST_BUILD_PATH = ../../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import sysconfig; print(\"lib.%s-%s\" %(sysconfig.get_platform(), sysconfig.get_python_version()))")
     LIBAPPARMOR_PATH=../../libraries/libapparmor/src/.libs/
     LD_LIBRARY_PATH=$(LIBAPPARMOR_PATH):$(PYTHON_DIST_BUILD_PATH)
     PYTHONPATH=..:$(PYTHON_DIST_BUILD_PATH)
--- /dev/null
+++ b/utils/test/README.md
@@ -0,0 +1,18 @@
+# Running individual tests
+
+Python's unittest allows individual tests to be executed by specifying the class name and the test on the command line.
+When running tests individually, the unittest framework executes the "setUp" and "tearDown" methods automatically.
+For more information, refer to the [unittest documentation](https://docs.python.org/3/library/unittest.html).
+
+Make sure to set the environment variables pointing to the in-tree apparmor modules, and the in-tree libapparmor and its python wrapper:
+
+```bash
+$ export PYTHONPATH=..:../../libraries/libapparmor/swig/python/build/$(/usr/bin/python3 -c "import sysconfig; print(\"lib.%s-%s\" %(sysconfig.get_platform(), sysconfig.get_python_version()))")
+$ export __AA_CONFDIR=.
+```
+
+To execute the test individually, run:
+
+```bash
+$ python3 ./test-tile.py ClassFoo.test_bar
+```
\ No newline at end of file