]> Kevux Git Server - controller/commitdiff
Update: Cgroup example controller script example to show running under a SystemD... development
authorKevin Day <Kevin@kevux.org>
Sat, 14 Sep 2024 21:02:06 +0000 (16:02 -0500)
committerKevin Day <Kevin@kevux.org>
Sat, 14 Sep 2024 21:02:06 +0000 (16:02 -0500)
This is not required, but it builds the structure to accommodate the over-engineered SystemD absurdity of an init system.
This is now more dynamic.

Also show different programs like browsers.
Also show firewall being set to startup.

16 files changed:
data/data/controller/example/cgroup/entries/chromium.entry
data/data/controller/example/cgroup/entries/eclipse.entry [deleted file]
data/data/controller/example/cgroup/entries/falkon.entry [new file with mode: 0644]
data/data/controller/example/cgroup/entries/firefox.entry
data/data/controller/example/cgroup/entries/setup_cgroups.entry [deleted file]
data/data/controller/example/cgroup/entries/startup.entry [new file with mode: 0644]
data/data/controller/example/cgroup/entries/terminator.entry [new file with mode: 0644]
data/data/controller/example/cgroup/rules/network/firewall.rule [new file with mode: 0644]
data/data/controller/example/cgroup/rules/program/chromium.rule
data/data/controller/example/cgroup/rules/program/eclipse.rule [deleted file]
data/data/controller/example/cgroup/rules/program/falkon.rule [new file with mode: 0644]
data/data/controller/example/cgroup/rules/program/firefox.rule
data/data/controller/example/cgroup/rules/program/terminator.rule [new file with mode: 0644]
data/data/controller/example/cgroup/rules/setup/cgroups.rule
data/data/controller/example/cgroup/settings/cgroup.fss [new file with mode: 0644]
data/data/controller/example/cgroup/systemd/setup_cgroup.service [new file with mode: 0644]

index 8e418377b4c717a45f7473e09848295ab87f235e..624d3a929f7ebd0c04f4494edda49785d5630e51 100644 (file)
@@ -1,4 +1,7 @@
 # fss-0005
+#
+# Helper entry for starting chromium using a sub-user account rule.
+#
 
 settings:
   mode helper
diff --git a/data/data/controller/example/cgroup/entries/eclipse.entry b/data/data/controller/example/cgroup/entries/eclipse.entry
deleted file mode 100644 (file)
index 7a3aedb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# fss-0005
-
-settings:
-  mode helper
-
-main:
-  start program eclipse asynchronous
diff --git a/data/data/controller/example/cgroup/entries/falkon.entry b/data/data/controller/example/cgroup/entries/falkon.entry
new file mode 100644 (file)
index 0000000..c899123
--- /dev/null
@@ -0,0 +1,10 @@
+# fss-0005
+#
+# Helper entry for starting falkon using a sub-user account rule.
+#
+
+settings:
+  mode helper
+
+main:
+  start program falkon asynchronous
index 5d5ff15b95dfc9a666cdbfebc0feaaadbd3c4779..7cbb4605adcf3a447400366972d6157e9ad508a8 100644 (file)
@@ -1,4 +1,7 @@
 # fss-0005
+#
+# Helper entry for starting firefox using a sub-user account rule.
+#
 
 settings:
   mode helper
diff --git a/data/data/controller/example/cgroup/entries/setup_cgroups.entry b/data/data/controller/example/cgroup/entries/setup_cgroups.entry
deleted file mode 100644 (file)
index 7a59836..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# fss-0005
-
-settings:
-  mode program
-
-main:
-  start setup cgroups
diff --git a/data/data/controller/example/cgroup/entries/startup.entry b/data/data/controller/example/cgroup/entries/startup.entry
new file mode 100644 (file)
index 0000000..e02826e
--- /dev/null
@@ -0,0 +1,26 @@
+# fss-0005
+#
+# Entry file for system startup tasks, setting up cgroup for sub-users.
+#
+# A sub-user is a second user in which some other user can switch to without a password and run processes in a more controlled, or perhaps jailed, environment.
+#
+# The Rules that utilize the cgroup for sub-users functionality generally use sudo to perform this task and run in helper mode with asynchronous to allow for the controller program to exit while the program executes as a forked process.
+#
+
+settings:
+  mode program
+
+  control_user 0
+  control_group 0
+  control_mode ug+rwx,o-rwx
+
+  session new
+
+main:
+  failsafe failure
+
+  start network firewall asynchronous
+  start setup cgroups
+
+failure:
+  print Controller Startup Failed.
diff --git a/data/data/controller/example/cgroup/entries/terminator.entry b/data/data/controller/example/cgroup/entries/terminator.entry
new file mode 100644 (file)
index 0000000..298787e
--- /dev/null
@@ -0,0 +1,10 @@
+# fss-0005
+#
+# Helper entry for starting terminator using a sub-user account rule.
+#
+
+settings:
+  mode helper
+
+main:
+  start program terminator asynchronous
diff --git a/data/data/controller/example/cgroup/rules/network/firewall.rule b/data/data/controller/example/cgroup/rules/network/firewall.rule
new file mode 100644 (file)
index 0000000..c459248
--- /dev/null
@@ -0,0 +1,10 @@
+# fss-000d
+#
+# Rule for loading the FLL firewall settings on system start.
+#
+
+setting:
+  name "Load firewall settings."
+
+command:
+  start /usr/local/fll/programs/shared/firewall restart
index 75d10f06aefb6f5498317e3b0232ff97d9329789..f332b7057dad7f6ad2e898a64ac476f8346fbaf2 100644 (file)
@@ -1,8 +1,31 @@
 # fss-000d
+#
+# Helper rule for starting chromium using a sub-user account.
+#
 
 settings:
-  name "Run Chromium"
-  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser
+  name "Run Chromoum as some_user."
+  cgroup existing user.slice/user-1000.slice/section-1.scope/user_xmpme/group/browser
+  environment DISPLAY
+  #user some_user
+  #group some_group
+  nice 5
+
+script:
+  start {
+    if [[ $(xhost | grep '^SI:localuser:some_user$') == "" ]] ; then
+      xhost SI:localuser:some_user
+    fi
+
+    if [[ $DISPLAY == "" ]] ; then
+      export DISPLAY=:0.0
+    fi
+
+    export WEBKIT_DISABLE_COMPOSITING_MODE=1
+  }
 
 command:
-  start chromium --disable-features=UserAgentClientHint
+
+  # Run as a custom user in which the current user has passwordless sudo access to.
+  start sudo -n --preserve-env=WEBKIT_DISABLE_COMPOSITING_MODE,DISPLAY -u some_user chromium-browser --disable-features=UserAgentClientHint
+  #start sudo -n --preserve-env=WEBKIT_DISABLE_COMPOSITING_MODE,DISPLAY -u some_user chromium-browser --disable-features=UserAgentClientHint --disable-web-security
diff --git a/data/data/controller/example/cgroup/rules/program/eclipse.rule b/data/data/controller/example/cgroup/rules/program/eclipse.rule
deleted file mode 100644 (file)
index 8b1020a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# fss-000d
-
-settings:
-  name "Run Eclipse"
-  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/eclipse
-
-command:
-  start eclipse
diff --git a/data/data/controller/example/cgroup/rules/program/falkon.rule b/data/data/controller/example/cgroup/rules/program/falkon.rule
new file mode 100644 (file)
index 0000000..f7458c5
--- /dev/null
@@ -0,0 +1,28 @@
+# fss-000d
+#
+# Helper rule for starting falcon using a sub-user account.
+#
+
+settings:
+  name "Run Falkon as some_user."
+  cgroup existing user.slice/user-1000.slice/section-1.scope/user_xmpme/group/browser
+  environment DISPLAY
+  #user some_user
+  #group some_group
+  nice 5
+
+script:
+  start {
+    if [[ $(xhost | grep '^SI:localuser:some_user$') == "" ]] ; then
+      xhost SI:localuser:some_user
+    fi
+
+    if [[ $DISPLAY == "" ]] ; then
+      export DISPLAY=:0.0
+    fi
+  }
+
+command:
+
+  # Run as a custom user in which the current user has passwordless sudo access to.
+  start sudo -n --preserve-env=DISPLAY -u some_user falkon
index 79b19f9c195627b168acc73da399375926784363..196d6d06c87a545d010d89be0834827f7fa4830b 100644 (file)
@@ -1,8 +1,28 @@
 # fss-000d
+#
+# Helper rule for starting firefox using a sub-user account.
+#
 
 settings:
-  name "Run Firefox (ESR)"
-  cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser
+  name "Run Firefox as some_user."
+  cgroup existing user.slice/user-1000.slice/section-1.scope/user_xmpme/group/browser
+  environment DISPLAY
+  #user some_user
+  #group some_group
+  nice 5
+
+script:
+  start {
+    if [[ $(xhost | grep '^SI:localuser:some_user$') == "" ]] ; then
+      xhost SI:localuser:some_user
+    fi
+
+    if [[ $DISPLAY == "" ]] ; then
+      export DISPLAY=:0.0
+    fi
+  }
 
 command:
-  start firefox-esr
+
+  # Run as a custom user in which the current user has passwordless sudo access to.
+  start sudo -n --preserve-env=DISPLAY -u some_user firefox
diff --git a/data/data/controller/example/cgroup/rules/program/terminator.rule b/data/data/controller/example/cgroup/rules/program/terminator.rule
new file mode 100644 (file)
index 0000000..79f373e
--- /dev/null
@@ -0,0 +1,28 @@
+# fss-000d
+#
+# Helper rule for starting terminator using a sub-user account.
+#
+
+settings:
+  name "Run Terminator as some_user."
+  cgroup existing user.slice/user-1000.slice/section-1.scope/user_xmpme/group/browser
+  environment DISPLAY
+  #user some_user
+  #group some_group
+  nice 5
+
+script:
+  start {
+    if [[ $(xhost | grep '^SI:localuser:some_user$') == "" ]] ; then
+      xhost SI:localuser:some_user
+    fi
+
+    if [[ $DISPLAY == "" ]] ; then
+      export DISPLAY=:0.0
+    fi
+  }
+
+command:
+
+  # Run as a custom user in which the current user has passwordless sudo access to.
+  start sudo -n --preserve-env=DISPLAY -u some_user terminator
index 87de7651cba5938c02151bce460bda6a29f3192f..b86e1cee668abc01aa31885e8cd0c46459619d2b 100644 (file)
 # fss-000d
 #
-# A cgroups2 example for systemd-based system using example user with example subdirectories and example programs.
+# Rule for auto-configuring specific CGroup settings for some users.
 #
-# This uses a 12-core system as an example.
-#
-# This is intended to be run as the user rather than as root.
-#
-# Example sizes:
-#  For 2GB: 2 * 1024 * 1024 * 1024.
+# This is setup to be run under a SystemD system and there is an example SystemD service file provided for this.
+# This can be run without SystemD using controller or controller as init.
+# In such cases, the cgroup paths could be further simplified as suggested in some commented out examples.
 #
 
 settings:
-  name "Setup Cgroups for User 1000, named "you""
+  name "Setup CGroups for users."
+
+  environment PATH
 
 script:
 
   start {
     main() {
-      local user="you"
-      local group="you"
-      local path_cgroup="/sys/fs/cgroup/"
-      local path_slice_1="${path_cgroup}user.slice/"
-      local path_slice_2="${path_slice_1}user-1000.slice/"
-      #local path_slice_3="${path_slice_2}" # Some systemd's might work without the service directory.
-      local path_slice_3="${path_slice_2}user@1000.service/" # Some systemd's only give access to this service directory (the '@' is a problem and requires quoting).
-      local path_user="${path_slice_3}user_${user}/"
-      local path_group="${path_user}group/"
-      local path_top_subtree="${path_cgroup}cgroup.subtree_control" # Modifying this likely requires root privileges.
-      local directories="browser eclipse untrusted"
-      local d=
-      local i=
-      local subtree="+cpu +cpuset +memory +pids"
+      # Example PATH containing the FLL programs at a custom isolated directory.
+      PATH=/usr/local/fll/programs/shared/:$PATH
 
-      # The user path is for restricting the user and should not grant permissions to user other than read and execute directory.
-      if [[ ! -d "${path_user}" ]] ; then
-        mkdir -p "${path_user}"
+      local settings=/etc/init/settings/cgroup.fss
+      local all_subtree=$(fss_extended_read -nl all_subtree 0 "${settings}")
+      local group_subtree=$(fss_extended_read -nl group_subtree 0 "${settings}")
+      local total=$(fss_extended_read -nt user "${settings}")
+      let -i i=0
 
-        if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_user}." ; return 1 ; fi
+      if [[ $total == "" ]] ; then
+        let total=0
       fi
 
-      chmod -R u+rwX,g+rX-w,o-rwx "${path_user}" &&
-      chgrp -R ${group} "${path_user}"
+      while [[ $i -lt $total ]] ; do
 
-      if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi
+        setup_cgroup $(fss_extended_read -nls user ${i} 0 "${settings}") $(fss_extended_read -nls user ${i} 1 "${settings}") $(fss_extended_read -nls user ${i} 2 "${settings}")
 
-      # The group path is for the user to restrict processes they run and must have ownership with write access.
-      if [[ ! -d "${path_group}" ]] ; then
-        mkdir -p "${path_group}"
+        let i++
+      done
+
+      return 0
+    \}
+
+    setup_cgroup() {
+      local user="${1}"
+      local user_id="user-${3}"
+      local group="${2}"
+      local path_cgroup="/sys/fs/cgroup/"
+      local path_group="group/"
+      local path_slice_1="user.slice/"
+      local path_slice_2="${path_slice_1}${user_id}.slice/"
+      local path_slice_3="${path_slice_2}section-1.scope/"
+      local path_user="${path_slice_3}user_${user}/"
+      #local path_user="user_${user}/" # Common SystemD designs prevent this cleaner path from being used.
+      #local path_systemd_control="/sys/fs/cgroup/user.slice/cgroup.subtree_control"
+      #local path_systemd_control_user="/sys/fs/cgroup/user.slice/${user_id}.slice/cgroup.subtree_control"
+      local path_systemd_procs_user="/sys/fs/cgroup/user.slice/${user_id}.slice/cgroup.procs"
+      local categories=$(fss_extended_read -nl categories 0 "${settings}")
+      local category=
+      local total=
+      local key=
+      local c=
+      local i=
+      local j=
 
-        if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi
+      # The user path is for restricting the user and should not grant permissions to user other than read and execute directory.
+      if [[ ! -d ${path_cgroup}${path_user} ]] ; then
+        mkdir -p ${path_cgroup}${path_user} || return 1
       fi
 
-      # Must have common ancestor with write acces, so fix setup from systemd to work with this one.
-      chmod -R u+rw+X,g+rX-w,o-rwx "${path_group}" &&
-      chown -R ${user}:${group} "${path_group}"
+      chmod u+rwX,g+rX-w,o-rwx ${path_cgroup}${path_slice_1} || return 1
+      chgrp ${group} ${path_cgroup}${path_slice_1} || return 1
 
-      if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${path_group}." ; return 1 ; fi
+      chmod u+rwX,g+rX-w,o-rwx ${path_cgroup}${path_slice_2} || return 1
+      chgrp ${group} ${path_cgroup}${path_slice_2} || return 1
 
-      # Make sure the user can manipulate subtrees (May fail if any path outside of ${path_slice_1} lacks things wanted by ${subtree}).
-      echo ${subtree} >> "${path_slice_1}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_1}cgroup.subtree_control." ; return 1 ; fi
+      chmod u+rwX,g+rX-w,o-rwx ${path_cgroup}${path_slice_3} || return 1
+      chgrp ${group} ${path_cgroup}${path_slice_3} || return 1
 
-      echo ${subtree} >> "${path_slice_2}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_2}cgroup.subtree_control." ; return 1 ; fi
+      chmod -R u+rwX,g+rX-w,o-rwx ${path_cgroup}${path_user} || return 1
+      chgrp -R ${group} ${path_cgroup}${path_user} || return 1
+
+      # The group path is for the user to restrict processes they run and must have ownership with write access.
+      if [[ ! -d ${path_cgroup}${path_user}${path_group} ]] ; then
+        mkdir -p ${path_cgroup}${path_user}${path_group} || return 1
+      fi
 
-      echo ${subtree} >> "${path_slice_3}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_3}cgroup.subtree_control." ; return 1 ; fi
+      chmod -R u+rw+X,g+rX-w,o-rwx ${path_cgroup}${path_user}${path_group} || return 1
+      chown -R ${user}:${group} ${path_cgroup}${path_user}${path_group} || return 1
 
-      echo ${subtree} >> "${path_slice_4}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_4}cgroup.subtree_control." ; return 1 ; fi
+      find ${path_cgroup}${path_user} -type d -exec chmod g+s '{}' ';' || return 1
 
-      echo ${subtree} >> "${path_user}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_user}cgroup.subtree_control." ; return 1 ; fi
+      # make sure the user can manipulate subtrees.
+      echo ${all_subtree} >> ${path_cgroup}cgroup.subtree_control || return 1
+      #echo ${all_subtree} >> ${path_systemd_control} || return 1
+      #echo ${all_subtree} >> ${path_systemd_control_user} || return 1
+      echo ${group_subtree} >> ${path_cgroup}${path_slice_1}cgroup.subtree_control || return 1
+      echo ${group_subtree} >> ${path_cgroup}${path_slice_2}cgroup.subtree_control || return 1
+      echo ${group_subtree} >> ${path_cgroup}${path_slice_3}cgroup.subtree_control || return 1
+      echo ${group_subtree} >> ${path_cgroup}${path_user}cgroup.subtree_control || return 1
+      echo ${group_subtree} >> ${path_cgroup}${path_user}${path_group}cgroup.subtree_control || return 1
 
-      echo ${subtree} >> "${path_group}cgroup.subtree_control"
-      if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_group}cgroup.subtree_control." ; return 1 ; fi
+      # must have common ancestort write acces, so fix setup from systemd to work with this one.
+      chgrp ${group} ${path_systemd_procs_user}
+      chmod g+w ${path_systemd_procs_user}
 
-      for d in ${directories} ; do
-        i="${path_group}${d}/"
+      for c in ${categories} ; do
+        i="${path_cgroup}${path_user}${path_group}${c}/"
 
         if [[ ! -d ${i} ]] ; then
           echo "Creating cgroup directory '${i}'."
 
-          mkdir -p "${i}" &&
-          chown -R ${user}:${group} "${i}" &&
-          chmod -R u+rw+X,g+rX-w,o-rwx "${i}" &&
-          chmod g+s "${i}"
-
-          if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${i}." ; return 1 ; fi
+          mkdir -p ${i} &&
+          chown -R ${user}:${group} ${i} &&
+          chmod -R u+rw+X,g+rX-w,o-rwx ${i} || exit 1
+          chmod g+s ${i} || exit 1
         fi
 
-        if [[ ${d} == "browser" ]] ; then
-          put_into "7516192768" "${i}memory.high" &&
-          put_into "8589934592" "${i}memory.max" &&
-          put_into "3-6" "${i}cpuset.cpus"
-        elif [[ ${d} == "eclipse" ]] ; then
-          put_into "3758096384" "${i}memory.high" &&
-          put_into "4294967296" "${i}memory.max" &&
-          put_into "5-8" "${i}cpuset.cpus"
+        if [[ $(fss_extended_read -nls "category_${c}" 0 0 "${settings}") != "" ]] ; then
+          category="category_${c}"
         else
-          put_into "858993459" "${i}memory.high" &&
-          put_into "1073741824" "${i}memory.max" &&
-          put_into "9-11" "${i}cpuset.cpus"
+          category="default"
         fi
 
-        if [[ $? -ne 0 ]] ; then echo "Failed to restrictions for ${d} at ${i}." ; return 1 ; fi
+        total=$(fss_extended_read -nt "${category}" "${settings}")
+        let j=0
+
+        if [[ $total == "" ]] ; then
+          let total=0
+        fi
+
+        while [[ $j -lt $total ]] ; do
+
+          key=$(fss_extended_read -nls "${category}" ${j} 0 "${settings}")
+
+          put_into $(fss_extended_read -nls "${category}" ${j} 1 "${settings}") "${i}${key}" || return 1
+
+          let j++
+        done
       done
 
       return 0
     \}
 
-     put_into() {
-       if [[ -e ${2} ]] ; then
-         echo ${1} > ${2} || return 1
-       fi
+    put_into() {
+      if [[ -e ${2} ]] ; then
+        echo ${1} > ${2} || return 1
+      fi
 
-       return 0
-     \}
+      return 0
+    \}
 
-     main
+    main
   }
diff --git a/data/data/controller/example/cgroup/settings/cgroup.fss b/data/data/controller/example/cgroup/settings/cgroup.fss
new file mode 100644 (file)
index 0000000..9b5c93e
--- /dev/null
@@ -0,0 +1,18 @@
+# fss-0001
+
+all_subtree +cpu +cpuset +memory +pids
+group_subtree +cpu +cpuset +memory +pids
+
+# For 2GB: 2 * 1024 * 1024 * 1024 = 2147483648.
+# For 1GB: 1024 * 1024 * 1024 = 1073741824
+# For 768MB: 1024 * 1024 * 768 = 805306368.
+default memory.high 805306368
+default memory.max 1073741824
+default cpuset.cpus 1-2
+
+categories browser untrusted
+
+category_browser memory.high 1073741824
+category_browser memory.max 1288490188
+
+user some_user some_group 1000
diff --git a/data/data/controller/example/cgroup/systemd/setup_cgroup.service b/data/data/controller/example/cgroup/systemd/setup_cgroup.service
new file mode 100644 (file)
index 0000000..1c1d221
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=Controller: Setup CGroup
+
+[Service]
+#Type=simple
+Type=oneshot
+User=0
+Group=0
+ExecStart=/usr/local/fll/programs/shared/controller -s /etc/init startup
+
+[Install]
+WantedBy=default.target