Add a fas-client setup task. Add a common-scripts task. Setup arm-releng/arm-qa groups to use them.

This commit is contained in:
Kevin Fenzi 2013-04-12 17:44:53 +00:00
parent 9259cadfc5
commit 89e3c725e4
11 changed files with 366 additions and 0 deletions

View file

@ -0,0 +1,41 @@
#!/bin/bash
if [ $# -lt 2 ]; then
echo "Usage: $0 [name] [script]"
exit 1;
fi
NAME=$1
SCRIPT=$2
LOCKDIR="/var/tmp/$NAME"
PIDFILE="$LOCKDIR/pid"
function cleanup {
rm -rf "$LOCKDIR"
}
RESTORE_UMASK=$(umask -p)
umask 0077
if ! mkdir "$LOCKDIR"; then
echo "$LOCKDIR already exists"
PID=$(cat "$PIDFILE")
if [ -n "$PID" ] && /bin/ps $PID > /dev/null
then
echo "$PID is still running"
/bin/ps -o user,pid,start,time,comm $PID
exit 1;
else
echo "$LOCKDIR exists but $PID is dead"
echo "Removing lockdir and re-running"
/bin/rm -rf $LOCKDIR
mkdir $LOCKDIR || exit
fi
fi
trap cleanup EXIT SIGQUIT SIGHUP SIGTERM
echo $$ > "$PIDFILE"
$RESTORE_UMASK
eval "$SCRIPT"

108
files/common-scripts/nag-once Executable file
View file

@ -0,0 +1,108 @@
#!/usr/bin/python -tt
# nag once
# take stdin and arguments: commandid time-to-ignore-same-output
# if we encounter any kind of error just output whatever we're given
# and prepend our own errors
# so we don't hurt things any worse :)
# copyright (c) 2011 Red Hat, inc
# gpl v2 blah blah
# skvidal - skvidal@fedoraproject.org
import tempfile
import sys
import time
import os
import stat
import glob
def translate_tti(tti):
# translate 1w, 2d, 3d, 1m, 2h, 55m etc to seconds here
if tti is None:
return None
seconds_per_unit = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800,}
if tti.isdigit():# just seconds
return int(tti)
return int(tti[:-1]) * seconds_per_unit[tti[-1]]
def get_cmdid_dir(cmdid):
"""return a path to a valid and safe cachedir"""
tmpdir="/var/tmp"
prefix = "nag-once:" + cmdid + "#"
dirpath = '%s/%s*' % (tmpdir, prefix)
cachedirs = sorted(glob.glob(dirpath))
for thisdir in cachedirs:
stats = os.lstat(thisdir)
if stat.S_ISDIR(stats[0]) and stat.S_IMODE(stats[0]) == 448 and stats[4] == os.getuid():
return thisdir
# make the dir (tempfile.mkdtemp())
cachedir = tempfile.mkdtemp(prefix=prefix, dir=tmpdir)
return cachedir
def main():
if len(sys.argv) < 2:
raise Exception("Usage: nag-once cmdid [time-to-ignore]")
cmdid = sys.argv[1]
# go through and remove stupid shit from cmdid
cmdid = cmdid.replace('/', '')
cmdid = cmdid.replace('#', '')
cmdid = cmdid.replace('..', '')
cmdid = cmdid.replace(';', '')
cmdid = cmdid.replace('|', '')
cmdid = cmdid.replace('&', '')
cmdid = cmdid.replace('\\', '')
now = time.time()
tti = None
if len(sys.argv) > 2:
tti = sys.argv[2]
tti = translate_tti(tti)
# make up or find our tempdir
mydir = get_cmdid_dir(cmdid)
old_output = None
old_date = 0
if os.path.exists(mydir + '/output'):
old_output = open(mydir + '/output').read()
old_date = os.lstat(mydir + '/output')[stat.ST_MTIME]
# take from stdin
#
theinput = sys.stdin.read()
try:
# at this point we have to handle any outputs more ourself b/c we've just read
# out of sys.stdin :(
if theinput != old_output or (tti and now - old_date > tti):
if theinput.strip(): # if there is nothing here, don't output and don't drop a \n on the end of it
print theinput,
fo = open(mydir + '/output', 'w')
fo.write(theinput)
fo.flush()
fo.close()
except Exception, e:
print >> sys.stderr, e
print >> sys.stderr, theinput
if __name__ == '__main__':
try:
main()
except Exception, e:
print >> sys.stderr, e
if not sys.stdin.isatty():
print >> sys.stderr, sys.stdin.read()

View file

@ -0,0 +1 @@
*/10 * * * * root /usr/local/bin/lock-wrapper fasClient "/bin/sleep $(($RANDOM \% 180)); /usr/bin/fasClient -i | /usr/local/bin/nag-once fassync 1d 2>&1"

View file

@ -0,0 +1,102 @@
[global]
; url - Location to fas server
url = https://admin.fedoraproject.org/accounts/
; temp - Location to generate files while user creation process is happening
temp = /var/db
{% if ansible_domain == 'qa.fedoraproject.org' %}
; Eventually, no box should use systems user to fasClient. systems has access
; to password hashes. But password hashes are needed for sudo unless the box
; uses pam_url
; login - username to contact fas
login = systems
; password - password for login name
password = {{ systemsUserPassword }}
{% else %}
; login - username to contact fas
login = {{ fedorathirdpartyUser }}
; password - password for login name
password = {{ fedorathirdpartyPassword }}
{% endif %}
; prefix - install to a location other than /
prefix = /
; modefile - Location of a file containing saved home directory modes
modefile = /var/lib/fas/client_dir_perms
; cla_group - Group for CLA requirements
cla_group = cla_done
[host]
; Group hierarchy is 1) groups, 2) restricted_groups 3) ssh_restricted_groups
; so if someone is in all 3, the client behaves the same as if they were just
; in 'groups'
; groups that should have a shell account on this system.
{% if fas_client_groups %}
groups = {{ fas_client_groups }}
{% else %}
groups = "sysadmin-main"
{% endif %}
; groups that should have a restricted account on this system.
; restricted accounts use the restricted_shell value in [users]
restricted_groups =
; ssh_restricted_groups: groups that should be restricted by ssh key. You will
; need to disable password based logins in order for this value to have any
; security meaning. Group types can be placed here as well, for example
; @hg,@git,@svn
{% if fas_client_ssh_groups %}
ssh_restricted_groups = {{ fas_client_ssh_groups }}
{% else %}
ssh_restricted_groups =
{% endif %}
; aliases_template: Gets prepended to the aliases file when it is generated by
; fasClient
aliases_template = /etc/aliases.template
[users]
; default shell given to people in [host] groups
shell = /bin/bash
; home - the location for fas user home dirs
home = /home/fedora
; home_backup_dir - Location home dirs should get moved to when a user is
; deleted this location should be tmpwatched
home_backup_dir = /home/fedora.bak
; ssh_restricted_app - This is the path to the restricted shell script. It
; will not work automatically for most people though through alterations it
; is a powerfull way to restrict access to a machine. An alternative example
; could be given to people who should only have cvs access on the machine.
; setting this value to "/usr/bin/cvs server" would do this.
{% if fas_client_restricted_app %}
ssh_restricted_app = {{ fas_client_restricted_app }}
{% else %}
ssh_restricted_app =
{% endif %}
; ssh_admin_app - This is the path to an app that an admin is allowed to use.
{% if fas_client_admin_app %}
ssh_admin_app = {{ fas_client_admin_app }}
{% else %}
ssh_admin_app =
{% endif %}
; restricted_shell - The shell given to users in the ssh_restricted_groups
restricted_shell = /sbin/nologin
; ssh_restricted_shell - The shell given to users in the ssh_restricted_groups
ssh_restricted_shell = /bin/bash
; ssh_key_options - Options to be appended to people ssh keys. Users in the
; ssh_restricted_groups will have the keys they uploaded altered when they are
; installed on this machine, appended with the options below.
ssh_key_options = no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty

View file

@ -0,0 +1 @@
fas_client_groups: "sysadmin-main,sysadmin-qa"

View file

@ -0,0 +1 @@
fas_client_groups: "sysadmin-main,sysadmin-releng"

View file

@ -1,3 +1,11 @@
[arm-releng]
arm03-releng01.arm.fedoraproject.org
arm03-releng02.arm.fedoraproject.org
arm03-releng03.arm.fedoraproject.org
arm03-releng04.arm.fedoraproject.org
[arm-qa]
arm03-builder05.arm.fedoraproject.org
[buildvm]
buildvm-01.phx2.fedoraproject.org

View file

@ -0,0 +1,17 @@
- name: Setup arm-qa hosts
hosts: arm-qa
user: root
gather_facts: False
tags:
- arm-qa
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- ${private}/vars.yml
tasks:
# This group uses fas_client for user management
- include: $tasks/fas_client.yml
# This group includes our common scripts
- include: $tasks/common_scripts.yml

View file

@ -0,0 +1,17 @@
- name: Setup arm-releng hosts
hosts: arm-releng
user: root
gather_facts: False
tags:
- arm-releng
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- ${private}/vars.yml
tasks:
# This group uses fas_client for user management
- include: $tasks/fas_client.yml
# This group includes our common scripts
- include: $tasks/common_scripts.yml

11
tasks/common_scripts.yml Normal file
View file

@ -0,0 +1,11 @@
---
#
# This task installs some common scripts to /usr/local/bin
# scripts are under $files/common-scripts
#
- name: Install common scripts
action: copy src=$item dest=/usr/local/bin/
with_fileglob: $files/common-scripts/*
tags:
- config

59
tasks/fas_client.yml Normal file
View file

@ -0,0 +1,59 @@
---
#
# This task sets up fasClient on a machine.
# It installs the fas-clients package, then the /etc/fas.conf and finally a cron job update.
#
#
# fas-clients is in the infrastructure repo.
# nss_db is needed to store user/group info.
#
- name: install package needed for fas-client
action: yum state=installed name=$item
with_items:
- fas-clients
tags:
- packages
- name: install nss_db on rhel hosts only
action: yum state=installed name=nss_db
only_if: "'${ansible_distribution}' == 'RedHat'"
tags:
- packages
#
# fasClients needs a valid /etc/fas.conf.
# There's vars used in this template:
#
# fas_client_groups = "sysadmin-main"
# fas_client_restricted_app = ""
# fas_client_admin_app = ""
# fas_client_ssh_groups = ""
#
# if desired, set them on a per host/group basis.
#
# Currently the default template is used, but could be modified on a host basis.
#
- name: setup /etc/fas.conf for client use
action: template src=$item dest=/etc/fas.conf owner=root mode=600
with_first_found:
- $files/fas-client/${ansible_fqdn}.fas.conf.j2
- $files/fas-client/${ansible_hostname}.fas.conf.j2
- $files/fas-client/${ansible_hostname}.fas.conf.j2
- $files/fas-client/fas.conf.j2
tags:
- config
#
# setup /etc/cron.d/ file to run sync every 10min
# TODO: use cron module when it's fixed
#
#- name: fas_client cron job
# cron: name="fas client" user=root cron_file=fas-client minute="*/10" job="/usr/bin/fasClient -i"
# tags:
# - config
#
- name: fas_client cron job
action: copy src=$files/fas-client/fas-client.cron dest=/etc/cron.d/fas-client owner=root mode=700
tags:
- config