Skip to content

Development

TPArchambault edited this page Sep 3, 2023 · 32 revisions

Development resources

Various development resources.

Python GTK+ 3 with Glade

python bindings

Development Notes

Task and issue specific observations and notes.

Development Environment setup

Fedora 38 - Tested 8/15/23

The current Pipfile specifies Python3.6 which is the shipped version of Python on the supported RHEL8 platform, however developing over Python 3.6 is become more difficult due to the fact that a number of virtual environment tools and modules no longer support 3.6.

Modifying the Pipfile to specify Python3.10 eliminated a number of Python 3.6 setup dependency issues with no observed issues to this point in time. If you decide to got this route, install the following python3.10 packages:

sudo dnf install python3.10
sudo dnf install python3.10-devel

Depending on the state of your system in terms of currently installed packages, you may or may not need to install the following:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo dnf install -y python-devel # python 3.11.+ is the FC38 default
sudo dnf install -y cairo cairo-devel python3-wheel pipenv gcc zlib-devel bzip2 bzip2-devel \
  readline-devel sqlite sqlite-devel openssl-devel tk-devel git python3-cairo-devel webkit2gtk4.0 \
  cairo-gobject-devel gobject-introspection-devel dbus-devel audit-libs-devel clang gtksourceview3 Xvfb

Fedora 34 through 37

The following was current with the state of the github repo at the time of its writing. These instructions have not been recently tested with the current repo and as such should be considered as a rough guideline. For instance, one recent feature, the embedded help system, has a dependency on the webkit2gtk4.0 package that is not in the following dnf install package list instructions. It was omitted since its availability and/or compatibility with other packages on the target platforms has not been verified.

Depending on the state of your system in terms of currently installed packages, you may or may not need to install the following:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo dnf install -y python-devel # python 3.9.+ is the default
sudo dnf install -y cairo cairo-devel python3-wheel gcc zlib-devel bzip2 bzip2-devel \
  readline-devel sqlite sqlite-devel openssl-devel tk-devel git python3-cairo-devel \
  cairo-gobject-devel gobject-introspection-devel dbus-devel audit-libs-devel clang gtksourceview3 Xvfb
pip install pipenv --user  # If your system Python version is >=3.7 see the note below.

Note: The current version of pipenv requires your system version of Python to be >=3.7. Since the fapolicy-analyzer project supports RHEL8 and its default Python version of 3.6, in order to configure a virtualenv that uses 3.6, an older release of pipenv can be installed with the following:

pip install pipenv==2022.8.5

Install the fapolicyd

Install the fapolicyd daemon and add your non-root development user to the fapolicyd group. You won't be able to deploy your trust changes nor start or stop the daemon directly, but the application will run. The daemon will need to be executed at least once to create

sudo dnf install fapolicyd
sudo usermod -a -G fapolicyd <development_user>

# Set the fapolicyd daemon to run in permissive mode. Modify /usr/lib/systemd/system/fapolicyd.service:
# ExecStart=/usr/sbin/fapolicyd --permissive
sudo <your choice of editor> /usr/lib/systemd/system/fapolicyd.service

# Start the daemon
sudo systemctl start fapolicyd.service

Clone the github fapolicy-analyzer repo

$ git clone https://github.com/ctc-oss/fapolicy-analyzer.git

Starting the virtual environment and fapolicy-analyzer

Note: In order for the fapolicy-analyzer to execute in a development environment as a non-root user, the rust layer must be built with the xdg feature. From the PR !901:

To use XDG in a development environment ensure the FEATURES file is present in the root of the workspace and add a line for xdg to it.

Consequently, echo xdg into the FEATURES file at the root of your repo tree.

$ cd fapolicy-analyzer
$ echo xdg > FEATURES

A make based command driver has been added to the project which provides a set of targets to invoke common development tasks. To install required python packages, build the bindings, and start the virtual environment execute the following:

make shell

which under the hood is executing the following with the develop argument to setup.py:

pipenv install --dev
pipenv shell
python3 setup.py [develop | install]

The application can then be invoked with the following:

python -m fapolicy_analyzer.ui

The make command driver

There are a number of make targets to kick-off common development tasks. Invoking make without a command-line target will list the higher level targets with a short summary:

$ make

  Usage: make [target]

       fapolicy-analyzer - High level common operation targets

     list     - Display common development targets
     shell    - Install deps, build bindings, start venv shell
     run      - Execute the fapolicy-analyzer
     test     - Execute all unit-tests
     lint     - Execute source code linting tools
     format   - Execute source code formatting
     check    - Perform pre-git push tests and formatting
     list-all - Display all targets

     Note: Options can be passed to fapolicy-analyzer by
           setting the OPTIONS environment variable, for example
             $ OPTIONS='-v' make run

     Note: Errors stop make, ignore them with the '-k' option:
             $ make -k [target]

Performance Profiling in the Development Environment

Python has a couple of profiler modules available, cProfile and profile, which can be used to easily capture profiling data. Analysis is another story...

Just start the fapolicy-analyzer.ui module as an argument to either of the above profilers:

(fapolicy-analyzer) [toma@fc34-dev fapolicy-analyzer]$ python -m cProfile -o cProf.fapa.out -m fapolicy_analyzer.ui

The profiler's '-o FILE' option specifies the output data file, otherwise upon termination an alphabetically sorted function list with runtime data will be displayed on stdout, which is probably not what you had in mind. But by specifying the output data file, you've got the data file in hand, and now have the option to sort and query it as desired, e.g.

$ python
>>> import pstats
>>> p = pstats.Stats('cProf.fapa.out')
>>> p.sort_stats('cumulative').print_stats(10)

Check out the version specific documentation at https://docs.python.org/3/library/profile.html to learn more about sorting and display options.