Enable classic confinement¶
When a snap needs system resources beyond what strict confinement and the available interfaces can provide, it needs classic confinement.
This page provides guidance on how to enable classic confinement, as well as example solutions for snaps that have extra plugin-specific configurations to accommodate it.
Set the confinement level¶
You can enable classic confinment with a single key in the project file:
confinement: classic
When built, the snap now has unsandboxed access to the system, like a traditional app or package.
Next, check for linting errors to look for low-hanging errors that Snapcraft can detect.
Lastly, you may also need to provide extra configuration for the main part’s plugin.
Request classic confinement on the Snap Store¶
A classically-confined snap requires approval from the Store team before you can distribute it on the Snap Store.
Submit your snap for review to get approval for classic confinement.
Identify problems with linters¶
When you first enable classic confinement, you should run an appropriate built-in linter to check for common errors and problems in the snap’s files.
Example project files with classic confinement¶
The following projects are sample solutions for combining classic confinement with specific plugins. These are only guidelines. Every case is different, so you may need to make other adjustments to your snap’s build to completely confine it.
Autotools plugin¶
autotools-classic-example is a project with a main part that uses the Autotools plugin.
autotools-classic-example project file
name: autotools-classic-example
version: "1.0"
summary: An example snap for an autotools project
description: |
Shows how to create a snap for an application that uses Autotools for
build and installation.
grade: devel
base: core22
confinement: classic
architectures:
amd64:
apps:
# Using the name of the snap as the key name allows the program to be invoked
# by its name.
autotools-classic-example:
command: usr/bin/autotools-classic-example
parts:
hello:
plugin: autotools
source: .
autotools-configure-parameters:
- LDFLAGS="
-Wl,-dynamic-linker=/snap/core22/current/lib64/ld-linux-x86-64.so.2
-Wl,-rpath=/snap/core22/current/lib/x86_64-linux-gnu"
- --prefix=/usr
Make plugin¶
makefile-lib-example is a project with a main part that uses the Make plugin.
makefile-lib-example project file
name: example-make-lib
base: core22
version: "0.1"
summary: An example snap for a Makefile project using a system library
description: |
Shows how to create a snap for an application that uses a Makefile for
build and installation.
grade: devel
confinement: classic
architectures:
amd64:
lint:
ignore:
- library
apps:
make-example:
command: bin/example-make-lib
parts:
make-example-part:
build-packages:
- wget2-dev
plugin: make
make-parameters:
- LDFLAGS="-Wl,-dynamic-linker=/snap/core22/current/lib64/ld-linux-x86-64.so.2
-Wl,-rpath=/snap/core22/current/lib/x86_64-linux-gnu"
source: .
CMake plugin¶
cmake-classic-example is a project with a main part that uses the CMake plugin.
cmake-classic-example project file
name: cmake-classic-example
base: core22
version: "0.1"
summary: An example classic snap for a CMake project
description: |
Shows how to create a classic confinement snap for an application that
uses CMake for build and installation.
grade: devel
confinement: classic
apps:
cmake-classic-example:
command: usr/bin/cmake-example
parts:
cmake-example:
plugin: cmake
cmake-parameters: [-DCMAKE_INSTALL_PREFIX=/usr]
build-attributes:
- enable-patchelf
source: .
Python plugin¶
python-ctypes-example is a project with a main part that uses the Python plugin.
python-ctypes-example project file
name: example-python-ctypes
base: core22
version: "0.1"
summary: An example snap for a Python project using ctypes
description: |
Shows how to create a snap for a Python application that uses ctypes to
access a system library.
grade: devel
confinement: classic
apps:
example-python-ctypes:
# This refers to the installed location of the program at build-time.
# When the snap is installed, it will be available as example-python-ctypes.
command: bin/test-ctypes.py
parts:
example-part:
source: .
plugin: python
# Override the build to perform a normal build then patch ctypes to fix the
# run-time library paths.
override-build: |
craftctl build
$CRAFT_PROJECT_DIR/snap/local/patch-ctypes.sh
# These packages need to be made available so that the build step can patch
# ctypes.
stage-packages:
- python3.10-minimal
- libpython3.10-minimal
- libpython3.10-stdlib
# This resolves warnings reported by the classic linter for Snapcraft 3.7.
build-attributes:
- enable-patchelf
Patch Python ctypes to load system libraries¶
If your app uses ctypes to access system libraries, it must be bundled with patched ctype files. In this sample, both the patch script and the diff are kept in the project as files for processing during build.
To craft this solution:
Copy the patch script into
snap/local/
and the diff file intosnap/local/patches/
.Stage the system libraries in the main part. The core22 base uses Python 3.10, so the packages are:
snapcraft.yaml¶stage-packages: - python3.10-minimal - libpython3.10-minimal - libpython3.10-stdlib
Override the part’s build to also run a shell script that patches the ctype files:
snapcraft.yaml¶override-build: | craftctl build $CRAFT_PROJECT_DIR/snap/local/patch-ctypes.sh
The plugin now builds the part like normal before running the patch script.
Build the snap. During build, the script looks for core Python modules that need to be patched and refer to libraries in the base snap.
Go plugin¶
golang-classic-example is a project with a main part that uses the Go plugin.
golang-classic-example project file
# golang-classic-example, a classically-confined project that uses the Go plugin
name: golang-classic-example
base: core22
version: "0.1"
summary: An example snap for a classic confinement golang project
description: |
Shows how to create a snap for an application written in the Go language
that uses classic confinement.
grade: devel
confinement: classic
apps:
golang-classic-example:
command: bin/main
parts:
golang-classic-example:
plugin: go
source: .
build-snaps: [go]
build-packages: [pkg-config, libzstd-dev]
build-environment:
- CGO_ENABLED: 1
- CGO_LDFLAGS_ALLOW: ".*"