diff --git a/subiquitycore/snap.py b/subiquitycore/snap.py new file mode 100644 index 00000000..1ef667c2 --- /dev/null +++ b/subiquitycore/snap.py @@ -0,0 +1,33 @@ +# Copyright 2024 Canonical, Ltd. +# +# 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 . + +import os + + +# Returns true if the current execution environment is inside a snap. +def is_snap(): + return os.getenv("SNAP_CONFINEMENT") is not None + + +# Returns true if the current execution environment is inside a strictly +# confined snap. +def is_snap_strictly_confined(): + return os.getenv("SNAP_CONFINEMENT", "classic") == "strict" + + +# Returns the snap name if the current execution context is inside a snap, +# otherwise None. +def snap_name(): + return os.getenv("SNAP_INSTANCE_NAME") diff --git a/subiquitycore/tests/test_snap.py b/subiquitycore/tests/test_snap.py new file mode 100644 index 00000000..f1fcf22d --- /dev/null +++ b/subiquitycore/tests/test_snap.py @@ -0,0 +1,58 @@ +# Copyright 2024 Canonical, Ltd. +# +# 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 . + +import unittest +from unittest.mock import patch + +from subiquitycore import snap + + +class TestSnap(unittest.TestCase): + @patch("os.getenv", return_value=None) + def test_is_snap(self, os_getenv): + self.assertFalse(snap.is_snap()) + os_getenv.assert_called_with("SNAP_CONFINEMENT") + os_getenv.reset_mock() + + os_getenv.return_value = "strict" + self.assertTrue(snap.is_snap()) + os_getenv.assert_called_with("SNAP_CONFINEMENT") + os_getenv.reset_mock() + + os_getenv.return_value = "classic" + self.assertTrue(snap.is_snap()) + os_getenv.assert_called_with("SNAP_CONFINEMENT") + os_getenv.reset_mock() + + @patch("os.getenv", return_value=None) + def test_snap_confinement(self, os_getenv): + self.assertFalse(snap.is_snap_strictly_confined()) + os_getenv.assert_called_with("SNAP_CONFINEMENT", "classic") + os_getenv.reset_mock() + + os_getenv.return_value = "strict" + self.assertTrue(snap.is_snap_strictly_confined()) + + os_getenv.return_value = "classic" + self.assertFalse(snap.is_snap_strictly_confined()) + + @patch("os.getenv", return_value=None) + def test_snap_name(self, os_getenv): + self.assertIsNone(snap.snap_name()) + os_getenv.assert_called_with("SNAP_INSTANCE_NAME") + os_getenv.reset_mock() + + os_getenv.return_value = "console-conf" + self.assertEqual(snap.snap_name(), "console-conf")