Skip to content

Commit

Permalink
Merge pull request #287 from ComputeCanada/mkproject_auto
Browse files Browse the repository at this point in the history
Add support for freeipa auto-membership rule
  • Loading branch information
cmd-ntrf authored Dec 4, 2023
2 parents 7e2318b + c3aeaa1 commit 94ba5b6
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 126 deletions.
216 changes: 182 additions & 34 deletions site/profile/files/accounts/account_functions.sh
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
#!/bin/bash

wait_id () {
local USERNAME=$1
local FOUND=0
for i in $(seq 1 12); do
if ! SSS_NSS_USE_MEMCACHE=no id $USERNAME &> /dev/null; then
sleep 5
else
FOUND=1
break
fi
done
if [ $FOUND -eq 0 ]; then
systemctl restart sssd
sleep 5
id $USERNAME &> /dev/null
return $?
fi
return 0
kexec () {
local TMP_KRB_CACHE=$(mktemp)
kinit -kt /etc/krb5.keytab -c ${TMP_KRB_CACHE} &> /dev/null &&
KRB5CCNAME=${TMP_KRB_CACHE} ${@} &&
kdestroy -c ${TMP_KRB_CACHE} &> /dev/null
rm -f $TMP_KRB_CACHE
}

mkhome () {
local USERNAME=$1

wait_id $USERNAME

if [ ! $? -eq 0 ]; then
echo "ERROR - ${USERNAME} is not showing up in SSSD after 1min - cannot make its home."
return 1
if id $USERNAME &> /dev/null; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
local USER_UID=$(SSS_NSS_USE_MEMCACHE=no id -u $USERNAME)
else
local USER_INFO=$(kexec ipa user-show ${USERNAME})
local USER_HOME=$(echo "${USER_INFO}" | grep -oP 'Home directory: \K(.*)$')
local USER_UID=$(echo "${USER_INFO}" | grep -oP 'UID: \K([0-9].*)')
fi

local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
local MNT_USER_HOME="/mnt${USER_HOME}"
local RSYNC_DONE=0
for i in $(seq 1 5); do
rsync -opg -r -u --chown=$USERNAME:$USERNAME --chmod=Dg-rwx,o-rwx,Fg-rwx,o-rwx,u+X /etc/skel.ipa/ ${MNT_USER_HOME}
rsync -opg -r -u --chown=$USER_UID:$USER_UID --chmod=Dg-rwx,o-rwx,Fg-rwx,o-rwx,u+X /etc/skel.ipa/ ${MNT_USER_HOME}
if [ $? -eq 0 ]; then
RSYNC_DONE=1
break
Expand All @@ -55,27 +44,186 @@ mkscratch () {
local USERNAME=$1
local WITH_HOME=$2

wait_id $USERNAME

if [ ! $? -eq 0 ]; then
echo "$USERNAME is not showing up in SSSD after 1min - cannot make its scratch."
return 1
if id $USERNAME &> /dev/null; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
local USER_UID=$(SSS_NSS_USE_MEMCACHE=no id -u $USERNAME)
else
local USER_INFO=$(kexec ipa user-show ${USERNAME})
local USER_HOME=$(echo "${USER_INFO}" | grep -oP 'Home directory: \K(.*)$')
local USER_UID=$(echo "${USER_INFO}" | grep -oP 'UID: \K([0-9].*)')
fi

local USER_SCRATCH="/scratch/${USERNAME}"
local MNT_USER_SCRATCH="/mnt/${USER_SCRATCH}"
local MNT_USER_SCRATCH="/mnt${USER_SCRATCH}"
if [[ ! -d "${MNT_USER_SCRATCH}" ]]; then
mkdir -p ${MNT_USER_SCRATCH}
if [ "$WITH_HOME" == "true" ]; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
local MNT_USER_HOME="/mnt${USER_HOME}"
ln -sfT ${USER_SCRATCH} "${MNT_USER_HOME}/scratch"
chown -h ${USERNAME}:${USERNAME} "${MNT_USER_HOME}/scratch"
chown -h ${USER_UID}:${USER_UID} "${MNT_USER_HOME}/scratch"
fi
chown -h ${USERNAME}:${USERNAME} ${MNT_USER_SCRATCH}
chown -h ${USER_UID}:${USER_UID} ${MNT_USER_SCRATCH}
chmod 750 ${MNT_USER_SCRATCH}
restorecon -F -R ${MNT_USER_SCRATCH}
echo "SUCCESS - ${USERNAME} scratch initialized in ${MNT_USER_SCRATCH}"
fi
}

mkproject() {
local GROUP=$1
local WITH_FOLDER=$2

if mkdir /var/lock/mkproject.$GROUP.lock; then
# A new group has been created
if [ "$WITH_FOLDER" == "true" ]; then
GID=$(SSS_NSS_USE_MEMCACHE=no getent group $GROUP 2> /dev/null | cut -d: -f3)
if [ $? -eq 0 ]; then
GID=$(kexec ipa group-show ${GROUP} | grep -oP 'GID: \K([0-9].*)')
fi
MNT_PROJECT_GID="/mnt/project/$GID"
if [ ! -d ${MNT_PROJECT_GID} ]; then
MNT_PROJECT_GROUP="/mnt/project/$GROUP"
mkdir -p ${MNT_PROJECT_GID}
chown root:${GID} ${MNT_PROJECT_GID}
chmod 2770 ${MNT_PROJECT_GID}
ln -sfT "/project/$GID" ${MNT_PROJECT_GROUP}
restorecon -F -R ${MNT_PROJECT_GID} ${MNT_PROJECT_GROUP}
echo "SUCCESS - ${GROUP} project folder initialized in ${MNT_PROJECT_GID}"
else
echo "WARNING - ${GROUP} project folder ${MNT_PROJECT_GID} already exists"
fi
fi
# We create the associated account in slurm
/opt/software/slurm/bin/sacctmgr add account $GROUP -i &> /dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS - ${GROUP} account created in SlurmDB"
fi
rmdir /var/lock/mkproject.$GROUP.lock
fi
}

modproject() {
local GROUP=$1
local WITH_FOLDER=$2
local USERNAMES="${@:3}"
# mkproject is currently running, we skip adding more folder under the project
if [ -d /var/lock/mkproject.$GROUP.lock ]; then
return
fi
local GROUP_LINK=$(readlink /mnt/project/${GROUP})
# mkproject has yet been ran for this group, skip it
if [[ "${WITH_FOLDER}" == "true" ]]; then
if [[ -z "${GROUP_LINK}" ]]; then
return
fi
else
if [[ $(/opt/software/slurm/bin/sacctmgr -n list account Name=${GROUP} | wc -l) -eq 0 ]]; then
return
fi
fi
# The operation that add users to a group would have operations with a uid.
# If we found none, $USERNAMES will be empty, and it means we don't have
# anything to add to Slurm and /project
if [[ ! -z "${USERNAMES}" ]]; then
local MNT_PROJECT="/mnt${GROUP_LINK}"
if [ "$WITH_FOLDER" == "true" ]; then
for USERNAME in $USERNAMES; do

if id $USERNAME &> /dev/null; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
local USER_UID=$(SSS_NSS_USE_MEMCACHE=no id -u $USERNAME)
else
local USER_INFO=$(kexec ipa user-show ${USERNAME})
local USER_HOME=$(echo "${USER_INFO}" | grep -oP 'Home directory: \K(.*)$')
local USER_UID=$(echo "${USER_INFO}" | grep -oP 'UID: \K([0-9].*)')
fi
local MNT_USER_HOME="/mnt${USER_HOME}"

mkdir -p "${MNT_USER_HOME}/projects"
chgrp "${USER_UID}" "${MNT_USER_HOME}/projects"
chmod 0755 "${MNT_USER_HOME}/projects"
ln -sfT "/project/${GROUP}" "${MNT_USER_HOME}/projects/${GROUP}"

local PRO_USER="${MNT_PROJECT}/${USERNAME}"
if [ ! -d "${PRO_USER}" ]; then
mkdir -p ${PRO_USER}

chown "${USER_UID}" "${PRO_USER}"
chmod 2700 "${PRO_USER}"
restorecon -F -R "${PRO_USER}"
echo "SUCCESS - ${USERNAME} project ${GROUP} folder initialized in ${PRO_USER}"
else
echo "WARNING - ${USERNAME} project ${GROUP} in ${MNT_PROJECT}/${USERNAME} already exists"
fi
done
fi
/opt/software/slurm/bin/sacctmgr add user ${USERNAMES} Account=${GROUP} -i &> /dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS - ${USERNAMES} added to ${GROUP} account in SlurmDB"
fi
else
# If group has been modified but no uid were found in the log, it means
# user(s) have been removed from the groups.
# We identify which ones by comparing Slurm account with group.
local SLURM_ACCOUNT=$(/opt/software/slurm/bin/sacctmgr list assoc account=$GROUP format=user --noheader -P | awk NF | sort)
local USER_GROUP=$(kexec ipa group-show ${GROUP} --raw | grep -oP 'uid=\K([a-z0-9]*)' | sort)
local USERNAMES=$(comm -2 -3 <(echo "$SLURM_ACCOUNT") <(echo "$USER_GROUP"))
if [[ ! -z "$USERNAMES" ]]; then
/opt/software/slurm/bin/sacctmgr remove user $USERNAMES Account=${GROUP} -i &> /dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS - removed ${USERNAMES//[$'\n']/ } from ${GROUP} account in SlurmDB"
else
echo "ERROR - removing ${USERNAMES//[$'\n']/ } from ${GROUP} account in SlurmDB"
fi
if [ "$WITH_FOLDER" == "true" ]; then
for USERNAME in $USERNAMES; do
if id $USERNAME &> /dev/null; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
else
local USER_INFO=$(kexec ipa user-show ${USERNAME})
local USER_HOME=$(echo "${USER_INFO}" | grep -oP 'Home directory: \K(.*)$')
fi
local MNT_USER_HOME="/mnt${USER_HOME}"
rm "${MNT_USER_HOME}/projects/$GROUP" &> /dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS - removed ${USERNAME} project symlink $USER_HOME/projects/$GROUP"
else
echo "ERROR - could not remove ${USERNAME} project symlink $USER_HOME/projects/$GROUP"
fi
done
fi
else
echo "WARNING - Could not find username to remove from project ${GROUP}"
fi
fi
}

delproject() {
local GROUP=$1
local WITH_FOLDER=$2

# A group has been removed.
# Since we do not want to delete any data we only remove the
# symlinks and remove the users from the slurm account.
local USERNAMES=$(/opt/software/slurm/bin/sacctmgr list assoc account=$GROUP format=user --noheader -P | awk NF | sort)
if [[ ! -z "$USERNAMES" ]]; then
/opt/software/slurm/bin/sacctmgr remove user $USERNAMES Account=${GROUP} -i &> /dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS - removed ${USERNAMES} from ${GROUP} account in SlurmDB"
else
echo "ERROR - could not remove ${USERNAME} from ${GROUP} account in SlurmDB"
fi
if [ "$WITH_FOLDER" == "true" ]; then
for USERNAME in $USERNAMES; do
if id $USERNAME &> /dev/null; then
local USER_HOME=$(SSS_NSS_USE_MEMCACHE=no getent passwd $USERNAME | cut -d: -f6)
else
local USER_INFO=$(kexec ipa user-show ${USERNAME})
local USER_HOME=$(echo "${USER_INFO}" | grep -oP 'Home directory: \K(.*)$')
fi
local MNT_USER_HOME="/mnt${USER_HOME}"
rm "${MNT_USER_HOME}/projects/$GROUP"
done
fi
fi
}
6 changes: 4 additions & 2 deletions site/profile/manifests/accounts.pp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
file { '/sbin/mkhome.sh':
content => epp('profile/accounts/mkhome.sh',
{
with_home => $with_home,
with_scratch => $with_scratch,
with_home => $with_home,
with_scratch => $with_scratch,
project_regex => $project_regex,
with_project => $with_project,
}
),
mode => '0755',
Expand Down
7 changes: 5 additions & 2 deletions site/profile/manifests/freeipa.pp
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,10 @@
],
environment => ["IPA_ADMIN_PASSWD=${ipa_passwd}"],
path => ['/bin', '/usr/bin', '/sbin','/usr/sbin'],
subscribe => Exec['ipa-install'],
subscribe => [
Exec['ipa-install'],
Package['mokey'],
],
}

exec { 'ipa_mokey_role_add_privilege':
Expand Down Expand Up @@ -599,7 +602,7 @@
# TODO: Fix server hostname to ipa.${int_domain_name}
exec { 'ipa_getkeytab_mokeyapp':
command => 'kinit_wrapper ipa-getkeytab -s $(grep -m1 -oP \'(host|server) = \K.+\' /etc/ipa/default.conf) -p mokeyapp -k /etc/mokey/keytab/mokeyapp.keytab', # lint:ignore:140chars
refreshonly => true,
creates => '/etc/mokey/keytab/mokeyapp.keytab',
require => [
File['kinit_wrapper'],
File['/etc/mokey/keytab']
Expand Down
6 changes: 6 additions & 0 deletions site/profile/templates/accounts/mkhome.sh.epp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
source /sbin/account_functions.sh

PROJECT_REGEX="<%= $project_regex %>"

tail -F /var/log/dirsrv/slapd-*/access |
grep --line-buffered -oP 'ADD dn=\"uid=\K([a-z0-9A-Z_]*)(?=,cn=users)' |
while read USERNAME; do
Expand All @@ -10,4 +12,8 @@ while read USERNAME; do
<% if $with_scratch { -%>
mkscratch $USERNAME <%= $with_home %>
<% } -%>

for PROJECT in $((id -Gn ${USERNAME} 2> /dev/null || kexec ipa user-show ${USERNAME} | grep 'Member of groups:') | grep -P -o "${PROJECT_REGEX}"); do
modproject ${PROJECT} <%= $with_project %> ${USERNAME}
done
done
Loading

0 comments on commit 94ba5b6

Please sign in to comment.