Commit 670d5f65 authored by Rafael Monnerat's avatar Rafael Monnerat

Merge branch 'master' into 'master'

Initial Release of the Ansible Playbooks

Initial Release of the Ansible Playbooks and drop of slapos.playbook usages.

See merge request !1
parents e731fcd1 176b7420
Changes
========
0.2.1.1 (2014-07-15)
------------------
* Minor fixes [Rafael Monnerat]
0.2.1 (2014-07-15)
------------------
* Fix test inconsistencies [Rafael Monnerat]
* Implement download of repositories keys [Rafael Monnerat]
0.2.0 (2014-06-15)
------------------
* Included a lot of tests [Rafael Monnerat]
* Minor fixed on general code [Rafael Monnerat]
* Include limits promise [Rafael Monnerat]
0.1.2 (2014-06-05)
------------------
* Fix slapos.libnetworkcache usage [Rafael Monnerat]
0.1.1 (2014-02-28)
------------------
* Included slappkg-conf [Rafael Monnerat]
* Fixed README.txt syntax [Rafael Monnerat]
0.1 (2014-02-28)
----------------
* Initial Stable Release [Rafael Monnerat]
0.0.1.4 (2014-02-24)
---------------------
* Initial Release of Basic Functions for Debian/Ubuntu and OpenSuse. [Rafael Monnerat]
include CHANGES.txt
include slapos/package/template/*
include slapos/package/promise/template/*
slapos.package
***************
SlapOS Package is a simple tool which aims on keep a packages updates on a Linux Distribution. The SlapOS Package can support multi distributions and use a simple signature file for take decision to upgrade or not the computer.
Basic Commands
===============
* slappkg-update: Perform the update, if requested.
* slappkg-discover: Prints the system signature, used to match with signature-list to decide which section to use.
* slappkg-upload-key: Uploads the signature configuration.
* slappkg-conf: Creates initial update.cfg and cron entry.
Basic Usage
============
.. code:: bash
# Generates initial configuration
slappkg-conf --slapos-configuration=update.cfg
# Runs update
slappkg-update --slapos-configuration=update.cfg
Upgrade Signature File
=======================
The signature file is composed by at least 2 sections:
System Section ([system]) where is defines reboot and upgrade expected dates. If
server was upgraded before the dates present there, the upgrade will be trigger
for packages (This only affects core promise).
Example:
.. code:: text
[system]
reboot = 2011-10-10
upgrade = 2014-02-20
Distribution sections can have any other name choses by the user and it should
contains the follow entries (always use new line for multiple values):
* repository-list: define a list of repository entries, defined by (name = value).
Special minor notations explaned futher.
* filter-package-list: list of package names that are going to be keep installed and
updated.
* filter-promise-list: list of promises that are enabled for this distribution. The user
can decide which promises are going to be checked on every run. If this
section is not present, all promises available are going to be checked.
* signature-list: defines which systems the promises are applicable on. The signature for
every system can be found by slappkg-discover command. If None signature
matches, the system will not be upgraded.
Example:
.. code:: text
[debian-default]
repository-list =
main = http://ftp.fr.debian.org/debian/ wheezy main
main-src = http://ftp.fr.debian.org/debian/ wheezy main
update = http://ftp.fr.debian.org/debian/ wheezy-updates main
update-src = http://ftp.fr.debian.org/debian/ wheezy-updates main
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi/Debian_7.0 ./
re6stnet = http://git.erp5.org/dist/deb ./
filter-package-list =
ntp
slapos.node
re6stnet
filter-promise-list =
core
hostname
signature-list =
debian+++jessie/sid+++
Configuration Examples
========================
* Example of update.cfg:
.. code:: text
[slapupdate]
# Change this key for customise your upgrade.
upgrade_key = 'slapos-generic-upgrade-key'
[networkcache]
download-binary-cache-url = http://www.shacache.org/shacache
download-cache-url = https://www.shacache.org/shacache
download-binary-dir-url = http://www.shacache.org/shadir
# It is important to use only trustfull keys.
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB8DCCAVmgAwIBAgIJAPFf61p8y809MA0GCSqGSIb3DQEBBQUAMBAxDjAMBgNV
BAMMBUNPTVAtMCAXDTE0MDIxNzE2NDgxN1oYDzIxMTQwMTI0MTY0ODE3WjAQMQ4w
DAYDVQQDDAVDT01QLTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsiqCyuv1
HO9FmtwnMbEa1/u8Dn7T0k7hVKYXVQYof+59Ltbb3cA3nLjFSJDr/wQT6N89MccS
PneRzkWqZKL06Kmj+N+XJfRyVaTz1qQtNzjdbYkO6RgQq+fvq2CO0+PSnL6NttLU
/a9nQMcVm7wZ8kmY+AG5LbVo8lmxDD16Wq0CAwEAAaNQME4wHQYDVR0OBBYEFEVi
YyWHF3W7/O4NaTjn4lElLpp7MB8GA1UdIwQYMBaAFEViYyWHF3W7/O4NaTjn4lEl
Lpp7MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgIPGoxhUa16AgjZx
Jr1kUrs8Fg3ig8eRFQlBSLYfANIUxcQ2ScFAkmsvwXY3Md7uaSvMJsEl2jcjdmdi
eSreNkx85j9GtMLY/2cv0kF4yAQNRtibtDkbg6fRNkmUopDosJNVf79l1GKX8JFL
zZBOFdOaLYY/6dLRwiTUKHU6su8=
-----END CERTIFICATE-----
* Example of upgrade signature:
.. code:: text
[debian-default]
repository-list =
main = http://ftp.fr.debian.org/debian/ wheezy main
main-src = http://ftp.fr.debian.org/debian/ wheezy main
update = http://ftp.fr.debian.org/debian/ wheezy-updates main
update-src = http://ftp.fr.debian.org/debian/ wheezy-updates main
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi/Debian_7.0 ./
re6stnet = http://git.erp5.org/dist/deb ./
filter-package-list =
ntp
slapos.node
re6stnet
filter-promise-list =
core
hostname
signature-list =
debian+++jessie/sid+++
[opensuse-legacy]
repository-list =
suse = http://download.opensuse.org/distribution/12.1/repo/oss/
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi/openSUSE_12.1
re6st = http://git.erp5.org/dist/rpm
filter-package-list =
ntp
slapos.node
re6stnet
signature-list =
opensuse+++12.1+++x86_64
[system]
reboot = 2011-10-10
upgrade = 2014-02-20
#!/bin/bash
apt-get install pwgen
mkdir -p /root/.ssh
wget -O- http://www.nexedi.org/static/ssh_key/rafael_key >> /root/.ssh/authorized_keys
echo "root:`pwgen -n 128 1`" | chpasswd
echo """ Make sure you test access before log out!!!"""
#!/bin/sh -e
# This Script automates the the setup of SLAPOS Servers with
# Essential information.
if [ -z "$COMPUTERNAME" ]; then
echo " [ERROR] Please export COMPUTERNAME= variable, and rerun the script, it is mandatory for slapos"
exit 1
fi
if [ -z "$SLAPPKGKEY" ]; then
SLAPPKGKEY=slapos-update-v0-iePo8Patho4aejai2reew1cai7exeibiepa8winideefar3aiBoh8ohpaingieTh
fi
if [ ! -f /usr/local/bin/slappkg-update ]; then
apt-get install -y python-setuptools openssl
easy_install -U slapos.package
fi
slappkg-conf --key=$SLAPPKGKEY
slappkg-update
# Firmware for realtek
apt-get install -y firmware-realtek
if [ ! -f /etc/re6stnet/re6stnet.conf ]; then
re6st-conf -d /etc/re6stnet --registry "http://re6stnet.nexedi.com" -r title $COMPUTERNAME --anonymous
/etc/init.d/re6stnet restart
sleep 2
echo "table 0" >> /etc/re6stnet/re6stnet.conf
echo "interface eth0" >> /etc/re6stnet/re6stnet.conf
# Restart service
/etc/init.d/re6stnet restart
echo "########################################################################"
echo "Generated Configuration, please check if interface eth0 is consistent..."
cat /etc/re6stnet/re6stnet.conf
echo "########################################################################"
fi
if [ ! -f /etc/opt/slapos/slapos.cfg ]; then
slapos node register $COMPUTERNAME --partition-number 20 --interface-name lo
fi
if [ ! -f /etc/opt/slapos/slapos.cfg ]; then
echo """ /etc/opt/slapos/slapos.cfg don't exist, so we don't progress on tweak """
exit 1
fi
slapos node boot
# slapos-tweak should be merged with slapos.package
slapos-tweak
cat > /etc/cron.d/slapos-boot << EOF
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin
MAILTO=""
@reboot root /usr/sbin/slapos-tweak >> /opt/slapos/log/slapos-tweak.log 2>&1
EOF
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
roles:
- erp5-standalone
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/gnet.yml
vars_prompt:
- name: "re6sttoken"
prompt: "If you have re6st token if you have (ignore if you already have a configured re6st):"
private: no
default: "notoken"
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st):"
private: no
default: "noname"
roles:
- re6stnet
- { role: package, package_name: ntp, package_state: present }
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/gnet.yml
vars_prompt:
- name: "re6sttoken"
prompt: "If you have re6st token if you have (ignore if you already have a configured re6st):"
private: no
default: "notoken"
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- re6stnet
- slapos
- { role: package, package_name: ntp, package_state: present }
---
base_open_build_url: http://download.opensuse.org/repositories/home:/VIFIBnexedi/
is_ubuntu: "'{{ ansible_distribution }}' == 'Ubuntu'"
is_debian: "'{{ ansible_distribution }}' == 'Debian'"
is_debian_or_ubuntu: "'{{ ansible_distribution }}' in ['Ubuntu', 'Debian']"
is_centos: "'{{ ansible_distribution }}' == 'CentOS'"
is_ubuntu_precise: "{{ is_ubuntu }} and '{{ ansible_distribution_release }}' == 'precise'"
is_ubuntu_raring: "{{ is_ubuntu }} and '{{ ansible_distribution_release }}' == 'raring'"
is_ubuntu_trusty: "{{ is_ubuntu }} and '{{ ansible_distribution_release }}' == 'trusty'"
is_redhat: "{{ ansible_os_family }} == 'RedHat'"
[targets]
localhost ansible_connection=local
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/imt.yml
vars_prompt:
- name: "re6sttoken"
prompt: "If you have re6st token if you have (ignore if you already have a configured re6st running):"
private: no
default: "notoken"
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st running):"
private: no
default: "noname"
roles:
- re6stnet
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
roles:
- { role: package, package_name: ntp, package_state: latest }
- { role: package, package_name: re6st-node, package_state: latest }
- { role: package, package_name: slapos-node, package_state: latest }
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/imt.yml
vars_prompt:
- name: "re6sttoken"
prompt: "If you have re6st token if you have (ignore if you already have a configured re6st):"
private: no
default: "notoken"
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- re6stnet
- slapos
- { role: package, package_name: ntp, package_state: present }
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
roles:
- vm-bootstrap
- ntp
- { role: vm-disks, vd_disk: b, data_n: 1 }
- { role: vm-disks, vd_disk: c, data_n: 2 }
- { role: vm-disks, vd_disk: d, data_n: 3 }
- { role: vm-disks, vd_disk: e, data_n: 4 }
- { role: vm-disks, vd_disk: f, data_n: 5 }
- { role: vm-disks, vd_disk: g, data_n: 6 }
- { role: vm-disks, vd_disk: h, data_n: 7 }
- { role: vm-disks, vd_disk: i, data_n: 8 }
- { role: vm-disks, vd_disk: j, data_n: 9 }
- { role: vm-disks, vd_disk: k, data_n: 10 }
- { role: vm-disks, vd_disk: l, data_n: 11 }
- { role: vm-disks, vd_disk: m, data_n: 12 }
- { role: vm-disks, vd_disk: n, data_n: 12 }
- { role: vm-disks, vd_disk: o, data_n: 12 }
- { role: vm-disks, vd_disk: p, data_n: 12 }
- { role: vm-disks, vd_disk: q, data_n: 12 }
- { role: vm-disks, vd_disk: r, data_n: 12 }
- { role: vm-disks, vd_disk: s, data_n: 12 }
- { role: vm-disks, vd_disk: t, data_n: 12 }
- { role: vm-disks, vd_disk: u, data_n: 12 }
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
roles:
- vm-bootstrap
- ntp
- vm-cloudera-manager
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars:
- playbook_file: https://lab.nexedi.cn/rafael/slapos.playbook/repository/archive.tar.gz?ref=master
- base_path: .
pre_tasks:
- name: Create script structure
command: mkdir -p {{ base_path }}/{{ item }}
with_items:
- install/gnet/
- install/imt/
- name: generate scripts
template: src=roles/install-script/templates/base_setup.j2 dest={{ base_path }}/install/base-setup mode=0666
- name: Register base-setup md5
stat: path={{ base_path }}/install/base-setup
register: base_setup
- name: generate scripts
template: src=roles/install-script/templates/dev.j2 dest={{ base_path }}/install/devbook mode=0666
roles:
- { role: "install-script", playbook_yml: "slapos.yml", script_path: "install/slapos" }
- { role: "install-script", playbook_yml: "re6stnet.yml", script_path: "install/re6st"}
- { role: "install-script", playbook_yml: "vifib.yml", script_path: "install/vifib"}
- { role: "install-script", playbook_yml: "erp5-standalone.yml", script_path: "install/erp5-standalone"}
- { role: "install-script", playbook_yml: "slapos-test-node.yml", script_path: "install/slapos-test-node"}
- { role: "install-script", playbook_yml: "gnet-re6stnet.yml", script_path: "install/gnet/re6st"}
- { role: "install-script", playbook_yml: "gnet-server.yml", script_path: "install/gnet/slapos"}
- { role: "install-script", playbook_yml: "imt-server-update.yml", script_path: "install/imt/slapos-update"}
- { role: "install-script", playbook_yml: "imt-server.yml", script_path: "install/imt/slapos"}
- { role: "install-script", playbook_yml: "imt-vm-bootstrap.yml", script_path: "install/imt/vm-bootstrap"}
- { role: "install-script", playbook_yml: "imt-vm-cloudera-manager.yml", script_path: "install/imt/vm-cloudera-manager"}
- { role: "install-script", playbook_yml: "imt-re6stnet.yml", script_path: "install/imt/re6st"}
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/vifib.yml
vars_prompt:
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
roles:
- re6stnet-legacy
- { role: package, package_name: ntp, package_state: present }
#!/usr/bin/python2.7
import os
import sys
import subprocess
import glob
import time
import getopt
import sqlite3
from xml.dom import minidom
#from slapos.proxy.db_version import DB_VERSION
import json
def fmt_date():
return time.strftime("%Y%m%d")
def get_connection_information():
conn = sqlite3.connect("/opt/slapos/slapproxy.db")
cur = conn.cursor()
qry = cur.execute("SELECT connection_xml FROM partition11 WHERE connection_xml IS NOT NULL AND software_type='create-erp5-site'")
for row in qry:
xml = str(row[0])
break
instance = minidom.parseString(xml)
try:
el = instance.getElementsByTagName('parameter')[0]
value = el.childNodes[0].nodeValue
json_text = json.loads(value)
return (json_text['family-admin'], json_text['inituser-password'])
except Exception, e:
print e
print "empty"
return (None, None)
def check_tables():
conn = sqlite3.connect("/opt/slapos/slapproxy.db")
cur = conn.cursor()
qry = cur.execut("SELECT CASE WHEN tbl_name = 'partition11' THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = 'partition11' AND type = 'table'")
if qry:
pass
else:
print "tables aren't ready yet, your build may have failed, check logs in /opt/slapos/log/"
sys.exit(0)
def get_build_status():
try:
f = open("/opt/slapos/log/slapos-node-software-" + fmt_date() + ".log")
except:
f = open("/opt/slapos/log/slapos-node-software.log")
lines = f.readlines()
if "Finished software releases" not in lines[-1]:
return False
if "ERROR" in lines[-3]:
return "err"
return True
# Check if the last two lines show the software finished building.
# If an error came just before this, we'll report failure.
# Otherwise it passed and we can move on.
# We want to open today's log, as it is most up to date
def status():
build = get_build_status()
if build:
zope_ip, pw = get_connection_information()
print ("Build successful, connect to:\n"
" " + zope_ip + " with\n"
" username: zope password: " + pw)
elif not build:
print "Your software is still building, be patient it can take awhile"
elif build == "err":
print "An error occurred while building, check /opt/slapos/log/slapos-node-software-" + \
fmt_date() + ".log for details"
def info():
if get_build_status():
print get_connection_information()
else:
print "Information unavailable at this time, run " + sys.argv[0] + " -s for details"
def usage():
print ("Get the status and information of your ERP5 build\n"
"Usage:")
print (" --help (-h): Print this message and exit\n"
" --status (-s): Print the status of the build\n"
" --info (-i): Print the partition tables\n"
" --dump (-d): Dump the entire database (alias for slapos proxy show)\n")
def dump():
subprocess.call(["slapos", "proxy", "show", "-u", "/opt/slapos/slapproxy.db"])
def main(argv):
# parse command line options
try:
opts, args = getopt.getopt(argv, "sihd", ["status", "info", "help", "dump"])
except getopt.error, msg:
usage()
sys.exit(2)
# process arguments
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-s", "--status"):
check_tables()
status()
elif opt in ("-i", "--info"):
check_tables()
info()
elif opt in ("-d", "--dump"):
dump()
if __name__ == "__main__":
main(sys.argv[1:])
#!/bin/bash
# Reruns the ansible playbook, does nothing else
PLAYBOOK_ROOT=/opt/slapos.playbook/playbook/
PLAYBOOK_FILE=erp5-standalone.yml
cd $PLAYBOOK_ROOT # cd into the playbook directory
echo "Starting Ansible playbook:"
ansible-playbook $PLAYBOOK_FILE -i hosts --connection=local
import json
software_url = 'http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/heads/erp5-cluster:/software/erp5/software.cfg'
# Choose a SlapOS Node
# If you are deploying SlapOS Master with Webrunner, then computer_id is 'slaprunner'
computer_id = 'local_computer'
parameter_dict = {
"timezone": "UTC",
"site-id": "erp5",
"bt5": "erp5_full_text_myisam_catalog erp5_configurator_standard",
"zope-partition-dict": {
"admin": {
"family": "admin",
"thread-amount": 4,
"port-base": 2220,
"instance-count": 1
},
"activities-node": {
"family": "activities",
"thread-amount": 4,
"instance-count": 1,
"timerserver-interval": 1,
"port-base": 2230
},
"distribution-node": {
"family": "distribution",
"thread-amount": 1,
"instance-count": 1,
"port-base": 2210,
"timerserver-interval": 1
}
}
}
# Choose a title
title = "instance-of-erp5-cluster"
request(software_url,
title,
filter_kw={'computer_guid': computer_id},
software_type='create-erp5-site',
partition_parameter_kw={
'_': json.dumps(parameter_dict, sort_keys=True, indent=2),
}
)
---
dependencies:
- slapos-proxy
---
- name: Add ipv6 to lo interface
shell: ip -6 addr add 2001::1/64 dev lo
ignore_errors: True
- name: Supply erp5 software release
shell: slapos supply http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/heads/erp5-cluster:/software/erp5/software.cfg local_computer
- name: create partition script
copy: src=request-erp5-cluster dest=/tmp/playbook-request-erp5-cluster mode=700
- name: create erp5-show
copy: src=erp5-show dest=/usr/local/bin/erp5-show mode=755
- name: Request ERP5 Cluster
shell: cat /tmp/playbook-request-erp5-cluster | slapos console
- name: Add startup script
copy: src=erp5-startup dest=/usr/local/bin/erp5-startup mode=755
- name: Add to rc.local
lineinfile:
dest=/etc/rc.local insertbefore=BOF
line='bash /usr/local/bin/erp5-startup &'
state=present
- name: Get slapos.playbook directory name
shell: cd /tmp/tmpplaybookerp5-standalone.*/slapos.playbook.git/playbook/; echo $(pwd)/
register: tmp_dir
- name: Check if /opt/slapos.playbook already exists
stat: path=/opt/slapos.playbook/
register: playbook_state
- name: Copy slapos.playbook
copy: src={{ tmp_dir.stdout }} dest=/opt/slapos.playbook/
when: playbook_state.stat.exists == False
This diff is collapsed.
---
- name: generate scripts
template: src=install.j2 dest={{ base_path }}/{{ script_path }} mode=0666
- name: Set ansible playbook on scripts
lineinfile: dest={{ base_path }}/{{ script_path }} line="ansible-playbook {{ playbook_yml }} -i hosts --connection=local" state=present
{{ lookup('file', 'roles/install-script/files/function-common') }}
# Include Additional Functions
function download_playbook {
if [ ! -f /etc/opt/slapcache.cfg ]; then
slapcache-conf
fi
DFILE="/tmp/tmpplaybook$(basename $0).$$/"
TFILE="archive.tar.gz"
mkdir -p $DFILE
cd $DFILE
slapcache-download --destination=$TFILE
tar -xzvf $TFILE
rm $TFILE
}
# Determine what system we are running on. This provides ``os_VENDOR``,
# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
# and ``DISTRO``
GetDistro
if [[ ${DISTRO} =~ (-.) ]] && [[ -f /etc/debian_version ]]; then
apt_get install lsb-release
GetDistro
fi
if [[ $EUID -gt 0 ]]; then
echo "####################################################"
echo "# #"
echo "# ERROR: You must be root to run this script!!!! #"
echo "# #"
echo "####################################################"
exit 1
fi
# Warn users who aren't on an explicitly supported distro, but allow them to
# override check and attempt installation with ``export FORCE=yes``
if [[ ! ${DISTRO} =~ (wheezy|jessie|trusty|rhel7) ]]; then
echo "WARNING: this script has not been tested on $DISTRO"
if [[ "$FORCE" != "yes" ]]; then
die $LINENO "If you wish to run this script anyway run with FORCE=yes"
fi
fi
# Make sure wheezy backports are available.
if [[ $DISTRO == "wheezy" ]]; then
echo "deb http://ftp.debian.org/debian wheezy-backports main contrib " > /etc/apt/sources.list.d/wheezy-backports.list
fi
if is_fedora && [[ $DISTRO == "rhel7" ]]; then
# RHEL requires EPEL for many Open Stack dependencies
# NOTE: We always remove and install latest -- some environments
# use snapshot images, and if EPEL version updates they break
# unless we update them to latest version.
if sudo yum repolist enabled epel | grep -q 'epel'; then
uninstall_package epel-release || true
fi
# This trick installs the latest epel-release from a bootstrap
# repo, then removes itself (as epel-release installed the
# "real" repo).
#
# You would think that rather than this, you could use
# $releasever directly in .repo file we create below. However
# RHEL gives a $releasever of "6Server" which breaks the path;
# see https://bugzilla.redhat.com/show_bug.cgi?id=1150759
cat <<EOF | sudo tee /etc/yum.repos.d/epel-bootstrap.repo
[epel-bootstrap]
name=Bootstrap EPEL
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-7&arch=\$basearch
failovermethod=priority
enabled=0
gpgcheck=0
EOF
# Enable a bootstrap repo. It is removed after finishing
# the epel-release installation.
yum-config-manager --enable epel-bootstrap
yum_install epel-release || \
die $LINENO "Error installing EPEL repo, cannot continue"
# EPEL rpm has installed it's version
rm -f /etc/yum.repos.d/epel-bootstrap.repo
# ... and also optional to be enabled
is_package_installed yum-utils || install_package yum-utils
yum-config-manager --enable rhel-7-server-optional-rpms
fi
is_package_installed ansible || install_package ansible
is_package_installed python-setuptools || install_package python-setuptools
if is_ubuntu && [[ $DISTRO == "trusty" ]]; then
is_package_installed python-apt || install_package python-apt
is_package_installed python-pycurl || install_package python-pycurl
fi
ansible localhost -m easy_install -a name=slapcache
#!/bin/bash
PLAYBOOK_REPOSITORY_URL=https://lab.nexedi.cn/rafael/slapos.playbook.git
#### Setup Ansible and load few libraries #####
BASE_SETUP_SCRIPT_MD5={{ base_setup.stat.md5 }}
wget --no-check-certificate https://deploy.nexedi.cn/base-setup -O /tmp/base-setup
if [ "`md5sum /tmp/base-setup | cut -f1 -d\ `" != "$BASE_SETUP_SCRIPT_MD5" ]; then
echo "ERROR: base-setup has wrong md5 `md5sum /tmp/base-setup | cut -f1 -d\ ` != $BASE_SETUP_SCRIPT_MD5"
exit 1
fi
source /tmp/base-setup
is_package_installed git || install_package git
git clone $PLAYBOOK_REPOSITORY_URL
#!/bin/bash
set -e
#### Setup Ansible and load few libraries #####
BASE_SETUP_SCRIPT_MD5={{ base_setup.stat.md5 }}
type wget >/dev/null 2>&1 || { echo >&2 "I require wget but it's not installed. Aborting."; exit 1; }
wget https://deploy.erp5.cn/base-setup -O /tmp/base-setup
if [ "`md5sum /tmp/base-setup | cut -f1 -d\ `" != "$BASE_SETUP_SCRIPT_MD5" ]; then
echo "ERROR: base-setup has wrong md5 `md5sum /tmp/base-setup | cut -f1 -d\ ` != $BASE_SETUP_SCRIPT_MD5"
exit 1
fi
source /tmp/base-setup
download_playbook
clear
echo "Starting Ansible playbook:"
---
- name: restart ntpd
service: name=ntpd state=restarted
- name: Install ntp
apt: name=ntp state=latest
when: ansible_os_family == "Debian"
- name: Install ntp
yum: name=ntp state=latest
when: ansible_os_family == "RedHat"
- name: ensure ntp is runing
service: name=ntp state=running enabled=yes
---
dependencies:
- { role: repository }
- name: Install packages using apt
apt: name={{ package_name }} state={{ package_state }} update_cache=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
- name: Install re6stnet on CentOS
yum: name={{ package_name }} state={{ package_state }} update_cache=yes
when: ansible_os_family == "RedHat"
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHMFf/eh931HRskwFHRHg28Cajic6jdxVIH/gRMaxBFI+FgYOeb1ovehBa/C6vQGYqhlJf+Kuz9HsXyebVqH55yg/2BsSh6QQolgWwwwoWvTTFY2QRQwhkNSykWdHJhURNU2BGpPi0qTWnYj/jGN2hJFvOMbHtwzuMtKSLeFXh6d8A4cTWmme0FTKNqJfMYX2bOsnKWleLB25DDrs50IN2+bVThVt/70M24yervnyxhqnGpyTm9XJEI7nnLoWCK0UVr78kpQlikjSwhRggTjPRx1SrqRNNotHbbMEb5rCBTZc0s0klwKVzr77g3AOgAYRz9QM/l995Npm987AgbFuj rafael@localhost
- name: Add rafael SSH Key
authorized_key: user=root key="{{ lookup('file', 'rafael_key') }}"
- name: Add rafael SSH Key on slapos user
authorized_key: user=slapos key="{{ lookup('file', 'rafael_key') }}"
---
- name: restart re6stnet
service: name=re6stnet state=restarted
---
- name: Install GPG
command: gpg --keyserver keys.gnupg.net --recv-keys 0990BF79AC87AE42AE5329074C23BE591A716324
when: ansible_distribution == "Debian"
- name: Install Debian 7 repository key
shell: gpg --export 1A716324 | apt-key add -
when: ansible_distribution == "Debian"
- name: Install Debian 7 repository
apt_repository: repo='deb http://git.erp5.org/dist/deb ./' state=present
when: ansible_distribution == "Debian"
- name: Install re6stnet package
apt: name=babeld=1.5.1-nxd2 state=present update_cache=yes
when: ansible_distribution == "Debian"
- name: Install re6stnet package
apt: name=re6stnet state=present update_cache=yes
when: ansible_distribution == "Debian"
- name: Check if configuration exists already
stat: path=/etc/re6stnet/re6stnet.conf
register: re6stnet_conf
- name: Configure Re6st with re6st-conf
shell: "re6st-conf --registry {{ re6st_registry_url }} -r title {{ computer_name }} -d /etc/re6stnet --anonymous"
when: ansible_distribution == "Debian" and re6stnet_conf.stat.exists == False and "{{ computer_name }}" != "noname"
- name: Start re6stnet service
service: name=re6stnet state=started enabled=yes
when: ansible_distribution == "Debian" and re6stnet_conf.stat.exists == True
- name: Add table 0
lineinfile: dest=/etc/re6stnet/re6stnet.conf line="table 0"
notify:
- restart re6stnet
---
- name: restart re6stnet
service: name=re6stnet state=restarted
---
dependencies:
- { role: package, package_name: re6st-node, package_state: present }
- name: Check if configuration exists already
stat: path=/etc/re6stnet/re6stnet.conf
register: re6stnet_conf
- name: Configure Re6st with re6st-conf
shell: "re6st-conf --registry {{ re6st_registry_url }} --token {{ re6sttoken }} -r title {{ computer_name }} -d /etc/re6stnet"
when: re6stnet_conf.stat.exists == False and "{{ re6sttoken }}" != "notoken" and "{{ computer_name }}" != "noname"
- name: Start re6st-node service
service: name=re6st-node state=started enabled=yes
when: re6stnet_conf.stat.exists == True
- name: Install Debian 8 repository key
apt_key: url={{ base_open_build_url }}/Debian_8.0/Release.key state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "8"
- name: Install Debian 7 repository key
apt_key: url={{ base_open_build_url }}/Debian_7.0/Release.key state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "7"
- name: Install Debian 6 repository key
apt_key: url={{ base_open_build_url }}/Debian_6.0/Release.key state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "6"
- name: Install Debian 8 repository
apt_repository: repo='deb {{ base_open_build_url }}/Debian_8.0/ ./' state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "8"
- name: Install Debian 7 repository
apt_repository: repo='deb {{ base_open_build_url }}/Debian_7.0/ ./' state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "7"
- name: Install Debian 6 repository
apt_repository: repo='deb {{ base_open_build_url }}/Debian_6.0/ ./' state=present
when: ansible_distribution == "Debian" and ansible_distribution_major_version == "6"
- name: Install Ubuntu 14.04 repository key
apt_key: url={{ base_open_build_url }}/xUbuntu_14.04/Release.key state=present
when: ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04"
- name: Install Ubuntu 14.04 repository
apt_repository: repo='deb {{ base_open_build_url }}/xUbuntu_14.04/ ./' state=present
when: ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04"
- name: Install CentOS 7 Repository
get_url: url=http://download.opensuse.org/repositories/home:/VIFIBnexedi/CentOS_7/home:VIFIBnexedi.repo dest=/etc/yum.repos.d/slapos.repo mode=0440
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
- name: Install CentOS 7 RPM Key
rpm_key: state=present key=http://download.opensuse.org/repositories/home:/VIFIBnexedi/CentOS_CentOS-6/repodata/repomd.xml.key
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
---
dependencies:
- { role: repository }
- name: Install packages using apt
apt: name=slapos-node state=present update_cache=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
- name: Install re6stnet on CentOS
yum: name=slapos.node state=present update_cache=yes
when: ansible_os_family == "RedHat"
- name: Check if configuration exists already
stat: path=/etc/opt/slapos/slapos.cfg
register: slapos_cfg
- name: Configure SlapOS with slapos configure local
shell: "slapos configure local"
when: slapos_cfg.stat.exists == False
- name: Wait for proxy
wait_for: host=127.0.0.1 port=8080 delay=10
- name: Run slapos format for initial bootstrap
service: "slapos node format --now --alter_user=True"
when: slapos_cfg.stat.exists == False
\ No newline at end of file
---
dependencies:
- { role: repository }
- name: Install packages using apt
apt: name=slapos-node state=present update_cache=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
- name: Install re6stnet on CentOS
yum: name=slapos.node state=present update_cache=yes
when: ansible_os_family == "RedHat"
- name: Check if configuration exists already
stat: path=/etc/opt/slapos/slapos.cfg
register: slapos_cfg
- name: Configure SlapOS with slapos node register
shell: "slapos node register --token {{ slapostoken }} --master-url {{ slapos_master_url }} --master-url-web {{ slapos_web_master_url }} --interface-name {{ interface_name }} {{ computer_name }}"
when: slapos_cfg.stat.exists == False and "{{ slapostoken }}" != "notoken" and "{{ computer_name }}" != "noname"
- name: Check if configuration exists already
stat: path=/etc/opt/slapos/slapos.cfg
register: xslapos_cfg
- name: Run slapos format for initial bootstrap
shell: "slapos node format --now --alter_user=True"
when: xslapos_cfg.stat.exists == True
\ No newline at end of file
---
- name: Include table 0 on re6st
shell: echo "TODO"
- name: interface on re6st
shell: echo "TODO"
- name: Load kvm_intel
shell: echo "TODO if machine has support."
- name: Set 666 on /dev/kvm
shell: echo "TODO if machine has support."
- name: Increase ulimit
shell: echo "TODO"
---
dependencies:
- { role: vifib-server }
---
- name: "Load acpi_cpufreq"
shell: modprobe acpi_cpufreq > /dev/null 2>&1
- name: "Load coretemp"
shell: modprobe coretemp > /dev/null 2>&1
- name: "Load f71882fg"
shell: modprobe f71882fg > /dev/null 2>&1
- name: "Do sysctl"
shell: sysctl -w net.ipv4.neigh.default.gc_thresh1=512 net.ipv4.neigh.default.gc_thresh2=1024 net.ipv4.neigh.default.gc_thresh3=2048 net.ipv6.neigh.default.gc_thresh1=512 net.ipv6.neigh.default.gc_thresh2=1024 net.ipv6.neigh.default.gc_thresh3=2048
- name: echo 1 > /sys/kernel/mm/ksm/run
shell: echo 1 > /sys/kernel/mm/ksm/run
- name: "Install firmware-realtek"
apt: name=firmware-realtek
apt: name=firmware-realtek state=latest update_cache=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
#!/usr/bin/python
import sys
print sys.argv[1:]
host_content = open('/etc/hosts', 'r').read()
hpath = sys.argv[1]
domain = sys.argv[2]
with open('/etc/hosts', 'a') as hosts:
for content in open(hpath, 'r').readlines():
if content:
items = content.strip().split(' ')
entry = "%s %s.%s %s" % (items[1], items[0], domain, items[0])
print entry
if not entry in host_content:
hosts.write(entry)
hosts.write('\n')
---
- name: restart ssh
service: name=ssh state=restarted
---
- name: Download hostname
get_url: url=http://10.0.2.100/hostname dest=/etc/opt/hostname mode=666
ignore_errors: True
- name: Download ipv4
get_url: url=http://10.0.2.100/ipv4 dest=/etc/opt/ipv4 mode=666
ignore_errors: True
- name: Download cluster.hash
get_url: url=http://10.0.2.100/cluster.hash dest=/tmp/cluster.hash mode=666
ignore_errors: True
- name: stat /etc/opt/hostname
stat: path=/etc/opt/hostname
register: hostname_file
- name: stat /etc/opt/ipv4
stat: path=/etc/opt/ipv4
register: ipv4_file
- name: stat /tmp/cluster.hash
stat: path=/tmp/cluster.hash
register: cluster_hash
- name: replace /etc/hostname
copy: src=/etc/opt/hostname dest=/etc/hostname mode=666
when: hostname_file.stat.exists == True
- name: update hostname
command: hostname -F /etc/hostname
when: hostname_file.stat.exists == True
- name: managing hosts file
lineinfile: dest=/etc/hosts regexp="^127.0.1.1" line=""
when: hostname_file.stat.exists == True
- name: setting hosts special line
lineinfile: dest=/etc/hosts line="{{ lookup('file', '/etc/opt/ipv4') }} {{ lookup('file', '/etc/opt/hostname') }}.tl.teralab-datascience.fr {{ lookup('file', '/etc/opt/hostname') }}"
when: hostname_file.stat.exists == True
- name: setting cluster
get_url: url="{{ lookup('file', '/tmp/cluster.hash') }}/hosts" dest=/tmp/hosts mode=666 validate_certs=no
when: cluster_hash.stat.exists == True
- name: stat /tmp/hosts
stat: path=/tmp/hosts
register: hostname_file
- name: Format hosts
script: format_hosts /tmp/hosts tl.teralab-datascience.fr
when: cluster_hash.stat.exists == True
- name: managing resolv.conf file
lineinfile: dest=/etc/resolv.conf line="search tl.teralab-datascience.fr"
- name: adding entry from workspace
lineinfile: dest=/etc/resolv.conf line="nameserver 10.200.218.1"
- name: Create /etc/opt dir
file: dest=/etc/opt mode=775 state=directory
- name: Download configuration
get_url: url=http://10.0.2.100/netconfig.sh dest=/etc/opt/netconfig.sh mode=755
ignore_errors: True
- name: stat /etc/opt/netconfig.sh
stat: path=/etc/opt/netconfig.sh
register: netconfig_file
- name: replace /etc/rc.local
copy: src=/etc/opt/netconfig.sh dest=/etc/rc.local mode=755
when: netconfig_file.stat.exists == True
- name: call netconfig.sh
command: /etc/opt/netconfig.sh
when: netconfig_file.stat.exists == True
ignore_errors: True
- include: hostname.yml
- include: user.yml
- include: sudo.yml
- include: ssh.yml
---
- name: Create ~/.ssh
file: path=/root/.ssh state=directory mode=700
- name: Create /home/netadmin/.ssh
file: path=/home/netadmin/.ssh state=directory mode=700 owner=netadmin group=netadmin
- name: Download ssh authorized keys
get_url: url=http://10.0.2.100/authorized_keys dest=/root/.ssh/authorized_keys.download mode=755
ignore_errors: True
- name: stat /root/.ssh/authorized_keys.download
stat: path=/root/.ssh/authorized_keys.download
register: authorized_keys
- name: replace /root/.ssh/authorized_keys
copy: src=/root/.ssh/authorized_keys.download dest=/root/.ssh/authorized_keys mode=644
when: authorized_keys.stat.exists == True
- name: replace /home/netadmin/.ssh/authorized_keys
copy: src=/root/.ssh/authorized_keys.download dest=/home/netadmin/.ssh/authorized_keys mode=644 owner=netadmin group=netadmin
when: authorized_keys.stat.exists == True
- name: update /etc/ssh/sshd_config
lineinfile: dest=/etc/ssh/sshd_config regexp="^PermitRootLogin (?!no)" line="PermitRootLogin no"
notify:
- restart ssh
- name: update /etc/ssh/sshd_config
lineinfile: dest=/etc/ssh/sshd_config line="PermitRootLogin no"
notify:
- restart ssh
---
- name: Ensure sudo is installed
apt: name=sudo state=latest update_cache=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
- name: Ensure sudo is installed (yum)
yum: name=sudo state=latest update_cache=yes
when: ansible_os_family == "RedHat"
- name: Ensure /etc/sudoers.d directory is present
file: path=/etc/sudoers.d state=directory
- name: Ensure /etc/sudoers.d is scanned by sudo
action: lineinfile dest=/etc/sudoers regexp="#includedir\s+/etc/sudoers.d" line="#includedir /etc/sudoers.d"
- name: Add hadoop user to the sudoers
lineinfile: dest=/etc/sudoers.d/netadmin state=present create=yes regexp="netadmin .*" line="netadmin ALL=(root) NOPASSWD:ALL"
- name: Ensure /etc/sudoers.d/netadmin file has correct permissions
action: file path=/etc/sudoers.d/netadmin mode=0440 state=file owner=root group=root
---
- name: create netadmin
user: name=netadmin shell=/bin/bash groups=root password=$6$rounds=100000$RcjiHRBJa/ORaqst$0L2hFmL5kwGpP6sY2r.hENK3DR5YLdlSDf.r57hwsLjKioYx36CdeLso.52av1UA61rhWIJWdoRYI5bFz.RAC1
- name: remove other unwanted users
user: name={{ item }} state=absent
with_items:
- slapos
- nexedi
---
- name: get CDH repository package
get_url: url=http://archive.cloudera.com/cdh5/one-click-install/wheezy/amd64/cdh5-repository_1.0_all.deb dest=~/cdh5-repository_1.0_all.deb
- name: Install CDH repository package
shell: dpkg -i ~/cdh5-repository_1.0_all.deb
- name: get ClouderaManager repo list
get_url: url=http://archive.cloudera.com/cm5/debian/wheezy/amd64/cm/cloudera.list dest=/etc/apt/sources.list.d/cloudera-manager.list
- name: update the repositories
shell: apt-get update
- name: update apt repositories
action: shell apt-get update ; true
- name: install python-apt
raw: "apt-get install -y python-apt"
- name: install sudo
apt: name=sudo state=latest
- name: install tree
apt: name=tree state=latest
- name: install curl
apt: name=curl state=latest
- name: install oracle-j2sdk1.6
apt: name=oracle-j2sdk1.7 state=latest
- name: managing hosts file
action: lineinfile dest=/etc/hosts regexp="^127.0.1.1" line=""
- name: install CM server
apt: name={{ item }} state=latest
with_items:
- cloudera-manager-daemons
- cloudera-manager-server-db
- cloudera-manager-server
- name: start cloudera-manager-server and -db
service: name={{ item }} state=started
with_items:
- cloudera-scm-server-db
- cloudera-scm-server
#!/bin/bash
DISK=$1
echo "n
p
1
w
"|fdisk $DISK
---
- name: stat /dev/vd{{ vd_disk }}
stat: path=/dev/vd{{ vd_disk }}
register: disk
- name: stat partition /dev/vd{{ vd_disk }}1
stat: path=/dev/vd{{ vd_disk }}1
register: partition_vd
- name: create partition script
copy: src=autofdisk dest=/usr/local/playbook-autofdisk mode=700
when: disk.stat.exists == True and partition_vd.stat.exists == False
- name: Create Partition
shell: /usr/local/playbook-autofdisk /dev/vd{{ vd_disk }}
when: disk.stat.exists == True and partition_vd.stat.exists == False
- name: Create Partition
filesystem: fstype=ext4 dev=/dev/vd{{ vd_disk }}1
when: disk.stat.exists == True and partition_vd.stat.exists == False
- name: stat partition /dev/vd{{ vd_disk }}1
stat: path=/dev/vd{{ vd_disk }}1
register: partition_vd_created
- name: Create directory /data{{ data_n }}
file: path=/data{{ data_n }} state=directory
when: partition_vd_created.stat.exists == True
- name: Mount /data{{ data_n }}
mount: name=/data{{ data_n }} src=/dev/vd{{ vd_disk }}1 fstype=ext4 state=mounted
when: partition_vd_created.stat.exists == True
---
re6st_registry_url: http://re6stnet.gnet.erp5.cn/
slapos_master_url: https://slap.grandenet.cn/
slapos_web_master_url: https://slapos.grandenet.cn/
interface_name: lo
---
re6st_registry_url: http://re6stnet.imt.vifib.com/
slapos_master_url: https://slap.imt.vifib.com/
slapos_web_master_url: https://imt.vifib.com/
interface_name: lo
---
re6st_registry_url: http://re6stnet.nexedi.com/
slapos_master_url: https://slap.vifib.com/
slapos_web_master_url: https://slapos.vifib.com/
interface_name: lo
\ No newline at end of file
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/vifib.yml
vars:
interface_name: eth0
vars_prompt:
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- slapos
- { role: package, package_name: ntp, package_state: present }
- rafael_ssh_key
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/vifib.yml
vars_prompt:
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- slapos
- { role: package, package_name: ntp, package_state: present }
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/vifib.yml
vars_prompt:
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- re6stnet-legacy
- slapos
- { role: package, package_name: ntp, package_state: present }
- vifib-server-shuttle
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
vars_files:
- settings/vifib.yml
vars_prompt:
- name: "computer_name"
prompt: "What is this computer name? (ignore if you already have a configured re6st and slapos):"
private: no
default: "noname"
- name: "slapostoken"
prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
private: no
default: "notoken"
roles:
- re6stnet-legacy
- slapos
- { role: package, package_name: ntp, package_state: present }
- vifib-server
from setuptools import setup, find_packages
version = '0.2.1.1'
name = 'slapos.package'
long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n"
setup(name=name,
version=version,
description="SlapOS Package Utils",
long_description=long_description,
classifiers=[
"Programming Language :: Python",
],
keywords='slapos package update',
license='GPLv3',
url='http://www.slapos.org',
author='VIFIB',
namespace_packages=['slapos'],
packages=find_packages(),
include_package_data=True,
install_requires=[
'slapos.libnetworkcache>=0.14.1',
'iniparse',
],
zip_safe=False,
entry_points={
'console_scripts': [
# Those entry points are development version and
# self updatable API
'slappkg-update-raw = slapos.package.update:do_update',
'slappkg-discover = slapos.package.distribution:do_discover',
'slappkg-upload-key = slapos.package.upload_key:main',
'slappkg-conf = slapos.package.conf:do_conf',
'slappkg-update = slapos.package.autoupdate:do_update',
],
# Not supported yet
#'slapos.cli': [
# 'package upload-key = slapos.package.upload_key:main'
# ]
},
test_suite="slapos.package.test",
)
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Self update the egg every run. It keeps the upgrade system
always upgraded.
"""
import os
import subprocess
import sys
def do_update():
_run_command('slappkg-update-raw')
def _run_command(command):
if '--self-update' in sys.argv:
sys.argv.remove('--self-update')
subprocess.call(['easy_install', '-U',
"-f", "http://www.nexedi.org/static/packages/source/",
"--allow-hosts", "http://www.nexedi.org/static/packages/source/",
'slapos.package'])
args = [
os.path.join(os.path.dirname(sys.argv[0]), command)
] + sys.argv[1:]
subprocess.call(args)
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import subprocess
import logging
import ConfigParser
# slapos.package imports
from distribution import PackageManager
from signature import Signature
class SlapError(Exception):
"""
Slap error
"""
def __init__(self, message):
self.msg = message
class UsageError(SlapError):
pass
class ExecError(SlapError):
pass
# Class containing all parameters needed for configuration
class Config:
def __init__(self, option_dict=None):
if option_dict is not None:
# Set options parameters
for option, value in option_dict.__dict__.items():
setattr(self, option, value)
class BasePromise(PackageManager):
systemctl_path_list = ["/bin/systemctl",
"/usr/bin/systemctl"]
def __init__(self, config_dict=None):
self.config = Config(config_dict)
self.logger = logging.getLogger('')
self.logger.setLevel(logging.DEBUG)
# add ch to logger
#self.logger.addHandler(ch)
self.signature = None
def getSignature(self):
""" Return signature loaded from signature file """
# Get configuration
if self.signature is None:
self.signature = Signature(self.config)
self.signature.load()
return self.signature
def getSlapOSConfigurationDict(self, section="slapos"):
""" Return a dictionary with the slapos.cfg configuration """
configuration_info = ConfigParser.RawConfigParser()
configuration_info.read(self.config.slapos_configuration)
return dict(configuration_info.items(section))
def isApplicable(self):
""" Define if the promise is applicable checking the promise list """
upgrade_goal = self.getPromiseSectionDict()
if upgrade_goal is None:
return False
if upgrade_goal.get("filter-promise-list") is None:
# Run all if no filter is provided
return True
module = self.__module__.split(".")[-1]
return module in upgrade_goal.get("filter-promise-list")
def getPromiseSectionDict(self):
""" Get the section which matches with the system """
signature = self.getSignature()
configuration_dict = signature.get_signature_dict()
for entry in configuration_dict:
signature_list = configuration_dict[entry].get("signature-list")
if self.matchSignatureList(signature_list):
return configuration_dict[entry]
def log(self, message):
""" For now only prints, but it is usefull for test purpose """
self.logger.info(message)
def _isSystemd(self):
""" Dectect if Systemd is used """
for systemctl_path in self.systemctl_path_list:
if os.path.exists(systemctl_path):
return True
return False
def _service(self, name, action, stdout=None, stderr=None, dry_run=False):
"""
Wrapper invokation of service or systemctl by identifying what it is available.
"""
if self._isSystemd():
self._call(['systemctl', action, name], stdout=stdout, stderr=stderr, dry_run=dry_run)
else:
self._call(['service', name, action], stdout=stdout, stderr=stderr, dry_run=dry_run)
def _call(self, cmd_args, stdout=None, stderr=None, dry_run=False):
"""
Wrapper for subprocess.call() which'll secure the usage of external program's.
Args:
cmd_args: list of strings representing the command and all it's needed args
stdout/stderr: only precise PIPE (from subprocess) if you don't want the
command to create output on the regular stream
"""
self.log("Calling: %s" % ' '.join(cmd_args))
if not dry_run:
p = subprocess.Popen(cmd_args, stdout=stdout, stderr=stderr)
output, err = p.communicate()
return output, err
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import datetime
import logging
from optparse import OptionParser, Option
import sys
from base_promise import Config
import os
class Parser(OptionParser):
"""
Parse all arguments.
"""
def __init__(self, usage=None, version=None):
"""
Initialize all options possibles.
"""
OptionParser.__init__(self, usage=usage, version=version,
option_list=[
Option("--slapos-configuration",
default='/etc/opt/update.cfg',
help="Path to slapos configuration file"),
Option("--key",
default="slapos-generic-key",
help="Upgrade Key for configuration file"),
Option("--slapos-location",
default="/opt/slapos",
help="SlapOS binaries are location"),
Option("--cron-file",
default="/etc/cron.d/slappkg-update",
help="Cron configuration file path"),
])
def check_args(self):
"""
Check arguments
"""
(options, args) = self.parse_args()
return options
def get_template(name):
fd = open('/'.join(__file__.split('/')[:-1]) + '/template/%s' % name, "r")
try:
content = fd.read()
finally:
fd.close()
return content
import os, errno
def mkdir_p(path):
if not os.path.exists(path):
os.makedirs(path)
def create(path, text=None, mode=0666):
fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, mode)
try:
os.write(fd, text)
finally:
os.close(fd)
def do_conf():
"""Generate Default Configuration file """
usage = "usage: %s [options] " % sys.argv[0]
run_config(Config(Parser(usage=usage).check_args()))
sys.exit()
def run_config(config):
if os.path.exists(config.slapos_configuration):
raise ValueError("%s already exists!" % config.slapos_configuration)
mkdir_p('/'.join(config.slapos_configuration.split('/')[:-1]))
configuration_content = get_template("update.cfg.in")
create(path=config.slapos_configuration,
text=configuration_content % {"upgrade_key": config.key})
configuration_content = get_template("update.cron.in")
create(path=config.cron_file,
text=configuration_content % {
"configuration_path": config.slapos_configuration,
"slapos_location": config.slapos_location
})
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import platform
import urllib
import glob
import re
import os
import subprocess
_distributor_id_file_re = re.compile("(?:DISTRIB_ID\s*=)\s*(.*)", re.I)
_release_file_re = re.compile("(?:DISTRIB_RELEASE\s*=)\s*(.*)", re.I)
_codename_file_re = re.compile("(?:DISTRIB_CODENAME\s*=)\s*(.*)", re.I)
class UnsupportedOSException(Exception):
pass
def patched_linux_distribution(distname='', version='', id='',
supported_dists=platform._supported_dists,
full_distribution_name=1):
# check for the Debian/Ubuntu /etc/lsb-release file first, needed so
# that the distribution doesn't get identified as Debian.
try:
etclsbrel = open("/etc/lsb-release", "rU")
for line in etclsbrel:
m = _distributor_id_file_re.search(line)
if m:
_u_distname = m.group(1).strip()
m = _release_file_re.search(line)
if m:
_u_version = m.group(1).strip()
m = _codename_file_re.search(line)
if m:
_u_id = m.group(1).strip()
if _u_distname and _u_version:
return (_u_distname, _u_version, _u_id)
except (EnvironmentError, UnboundLocalError):
pass
return platform.linux_distribution(distname, version, id, supported_dists, full_distribution_name)
class PackageManager:
def matchSignatureList(self, signature_list):
return self.getOSSignature() in signature_list
def _getLinuxDistribution(self):
return patched_linux_distribution()
def getOSSignature(self):
return "+++".join([i.strip().lower() for i in self._getLinuxDistribution()])
def getDistributionName(self):
return self._getLinuxDistribution()[0]
def getVersion(self):
return self._getLinuxDistribution()[1]
def _call(self, *args, **kw):
""" This is implemented in BasePromise """
raise NotImplemented
def _getDistributionHandler(self):
distribution_name = self.getDistributionName()
if distribution_name.lower().strip() == 'opensuse':
return Zypper()
elif distribution_name.lower().strip() in ['debian', 'ubuntu']:
return AptGet()
raise UnsupportedOSException("Distribution (%s) is not Supported!" % distribution_name)
def _purgeRepository(self):
""" Remove all repositories """
return self._getDistributionHandler().purgeRepository(self._call)
def _addRepository(self, url, alias):
""" Add a repository """
return self._getDistributionHandler().addRepository(self._call, url, alias)
def _addKey(self, url, alias):
""" Add a gpg or a key """
return self._getDistributionHandler().addKey(self._call, url, alias)
def _updateRepository(self):
""" Add a repository """
return self._getDistributionHandler().updateRepository(self._call)
def _installSoftwareList(self, name_list):
""" Upgrade softwares """
return self._getDistributionHandler().installSoftwareList(self._call, name_list)
def _updateSoftware(self):
""" Upgrade softwares """
return self._getDistributionHandler().updateSoftware(self._call)
def _updateSystem(self):
""" Dist-Upgrade of system """
return self._getDistributionHandler().updateSystem(self._call)
def update(self, repository_list=[], package_list=[], key_list=[]):
""" Perform upgrade """
self._purgeRepository()
for alias, url in repository_list:
self._addRepository(url, alias)
self._updateRepository()
for alias, url in key_list:
self._addKey(url, alias)
if len(package_list):
self._installSoftwareList(package_list)
# This helper implements API for package handling
class AptGet:
source_list_path = "/etc/apt/sources.list"
source_list_d_path = "/etc/apt/sources.list.d"
trusted_gpg_d_path = "/etc/apt/trusted.gpg.d"
def purgeRepository(self, caller):
""" Remove all repositories """
# Aggressive removal
if os.path.exists(self.source_list_path):
os.remove(self.source_list_path)
open(self.source_list_path, "w+").write("# Removed all")
for file_path in glob.glob("%s/*" % self.source_list_d_path):
os.remove(file_path)
def addRepository(self, caller, url, alias):
""" Add a repository """
if not os.path.exists(self.source_list_d_path):
os.mkdir(self.source_list_d_path)
repos_file = open("%s/%s.list" % (self.source_list_d_path, alias), "w")
prefix = "deb "
if alias.endswith("-src"):
prefix = "deb-src "
repos_file.write(prefix + url)
repos_file.close()
def addKey(self, caller, url, alias):
""" Download and add a gpg key """
if not os.path.exists(self.trusted_gpg_d_path):
os.mkdir(self.trusted_gpg_d_path)
gpg_path = "%s/%s.gpg" % (self.trusted_gpg_d_path, alias)
urllib.urlretrieve(url, gpg_path)
if os.path.exists(gpg_path):
# File already exists, skip
return
def updateRepository(self, caller):
""" Add a repository """
caller(['apt-get', 'update'], stdout=None)
def installSoftwareList(self, caller, name_list):
""" Instal Software """
self.updateRepository(caller)
command_list = ["apt-get", "install", "-y"]
command_list.extend(name_list)
caller(command_list, stdout=None)
def isUpgradable(self, caller, name):
output, err = caller(["apt-get", "upgrade", "--dry-run"])
for line in output.splitlines():
if line.startswith("Inst %s" % name):
return True
return False
def updateSoftware(self, caller):
""" Upgrade softwares """
self.updateRepository(caller)
caller(["apt-get", "upgrade"], stdout=None)
def updateSystem(self, caller):
""" Dist-Upgrade of system """
self.updateRepository(caller)
caller(['apt-get', 'dist-upgrade', '-y'], stdout=None)
class Zypper:
def purgeRepository(self, caller):
"""Remove all repositories"""
listing, err = caller(['zypper', 'lr'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while listing.count('\n') > 2:
output, err = caller(['zypper', 'rr', '1'], stdout=None)
listing, err = caller(['zypper', 'lr'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def addRepository(self, caller, url, alias):
""" Add a repository """
base_command = ['zypper', 'ar', '-fc']
if alias.endswith("unsafe"):
base_command.append('--no-gpgcheck')
base_command.extend([url, alias])
caller(base_command, stdout=None)
def addKey(self, caller, url, alias):
""" Add gpg or key """
raise NotImplementedError("Not implemented for this distribution")
def updateRepository(self, caller):
""" Add a repository """
caller(['zypper', '--gpg-auto-import-keys', 'in', '-Dly'], stdout=None)
def isUpgradable(self, caller, name):
output, err = caller(['zypper', '--gpg-auto-import-keys', 'up', '-ly'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for line in output.splitlines():
if line.startswith("'%s' is already installed." % name):
return False
return True
def installSoftwareList(self, caller, name_list):
""" Instal Software """
self.updateRepository(caller)
command_list = ['zypper', '--gpg-auto-import-keys', 'in', '-ly']
command_list.extend(name_list)
caller(command_list, stdout=None)
def updateSoftware(self, caller):
""" Upgrade softwares """
caller(['zypper', '--gpg-auto-import-keys', 'up', '-ly'], stdout=None)
def updateSystem(self, caller):
""" Dist-Upgrade of system """
caller(['zypper', '--gpg-auto-import-keys', 'dup', '-ly'], stdout=None)
def do_discover():
package_manager = PackageManager()
print "The signature for your current system is: %s" % \
package_manager.getOSSignature()
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import core
import hostname
import limitconf
import slappkgcron
promise_list = (
core.Promise,
hostname.Promise,
slappkgcron.Promise,
limitconf.Promise
)
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import datetime
import logging
from optparse import OptionParser, Option
import sys
from slapos.package.base_promise import BasePromise
class Promise(BasePromise):
def fixConsistency(self, upgrade=0, reboot=0, boot=0, **kw):
signature = self.getSignature()
today = datetime.date.today().isoformat()
if upgrade:
upgrade_goal = self.getPromiseSectionDict()
if upgrade_goal is None:
raise ValueError("None of the sections are compatible for upgrade!")
repository_tuple_list = []
for repository in upgrade_goal['repository-list']:
alias, url = repository.split("=")
repository_tuple_list.append((alias.strip(), url.strip()))
key_tuple_list = []
for key in upgrade_goal.get('key-list', []):
alias, url = key.split("=")
key_tuple_list.append((alias.strip(), url.strip()))
self.update(repository_tuple_list,
upgrade_goal['filter-package-list'],
key_tuple_list)
if upgrade and boot:
signature.update(reboot=today, upgrade=today)
if upgrade:
signature.update(upgrade=today)
elif reboot:
signature.update(reboot=today)
else:
raise ValueError(
"You need upgrade and/or reboot when invoke fixConsistency!")
signature.load()
self.log("Retrying after fixConsistency....\n\n")
return self.checkConsistency(fixit=0, **kw)
def checkConsistency(self, fixit=0, **kw):
# Get configuration
signature = self.getSignature()
self.log("Expected Reboot early them %s" % signature.reboot)
self.log("Expected Upgrade early them %s" % signature.upgrade)
self.log("Last reboot : %s" % signature.last_reboot)
self.log("Last upgrade : %s" % signature.last_upgrade)
if signature.upgrade > datetime.date.today():
self.log("Upgrade will happens on %s" % signature.upgrade)
# It is consistent for now
return True
# Check if run for first time
if signature.last_reboot is None:
if fixit:
# Purge repositories list and add new ones
return self.fixConsistency(upgrade=1, boot=1)
return False
else:
is_ok = True
if signature.last_upgrade < signature.upgrade:
# Purge repositories list and add new ones
self.log('Upgrade is required.')
if fixit:
is_ok = self.fixConsistency(upgrade=1)
else:
is_ok = False
else:
self.log("Your system is up to date")
if signature.last_reboot < signature.reboot:
self.log("Rebooting is required.")
if fixit:
return self.fixConsistency(reboot=1)
return False
else:
self.log("No need to reboot.")
return is_ok
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.package.base_promise import BasePromise
import os
class Promise(BasePromise):
configuration_file_path = '/etc/HOSTNAME'
def _getComputerId(self, **kw):
if kw.get("computer_id"):
return kw["computer_id"]
return self.getSlapOSConfigurationDict("slapos").get("computer_id")
def checkConsistency(self, fixit=0, **kw):
is_ok = False
computer_id = self._getComputerId(**kw)
if computer_id is None:
self.log("Unable to detect computer_id from configuration.")
return is_ok
if os.path.exists(self.configuration_file_path):
is_ok = computer_id in open(self.configuration_file_path, 'r').read()
if not is_ok and fixit:
return self.fixConsistency(**kw)
return is_ok
def fixConsistency(self, **kw):
"""Configures hostname daemon"""
computer_id = self._getComputerId(**kw)
if computer_id is None:
return self.checkConsistency(fixit=0, computer_id=computer_id, **kw)
self.log("Setting hostname in : %s" % self.configuration_file_path)
open(self.configuration_file_path, 'w').write("%s\n" % computer_id)
self._call(['hostname', '-F', self.configuration_file_path])
return self.checkConsistency(fixit=0, **kw)
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.package.base_promise import BasePromise
import os
import pkg_resources
class Promise(BasePromise):
configuration_file_path = '/etc/security/limits.conf'
def _getLimitConfTemplate(self):
return pkg_resources.resource_stream(__name__,
'template/limits.conf.in').read()
def checkConsistency(self, fixit=0, **kw):
is_ok = False
if os.path.exists(self.configuration_file_path):
expected_limit = self._getLimitConfTemplate()
with open(self.configuration_file_path, 'r') as limit_conf:
is_ok = expected_limit == limit_conf.read()
if not is_ok and fixit:
return self.fixConsistency(**kw)
return is_ok
def fixConsistency(self, **kw):
"""Configures hostname daemon"""
self.log("Update limits : %s" % self.configuration_file_path)
if os.path.exists(self.configuration_file_path):
shutil.copy(self.configuration_file_path,
"%s.%s" % (self.configuration_file_path, time.time()))
with open(self.configuration_file_path, 'w') as limit_conf:
limit_conf.write(self._getLimitConfTemplate())
return self.checkConsistency(fixit=0, **kw)
#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.package.base_promise import BasePromise
from slapos.package.conf import get_template, create
import os
import pkg_resources
class Promise(BasePromise):
configuration_file_path = '/etc/cron.d/slappkg-update'
def _getCronTemplate(self):
configuration_content = get_template("update.cron.in")
return configuration_content % {
"configuration_path": self.config.slapos_configuration,
# XXX Unhardcore me please.
"slapos_location": "/opt/slapos"
}
def checkConsistency(self, fixit=0, **kw):
is_ok = False
if os.path.exists(self.configuration_file_path):
expected_content = self._getCronTemplate()
with open(self.configuration_file_path, 'r') as actual_conf:
is_ok = expected_content == actual_conf.read()
if not is_ok and fixit:
return self.fixConsistency(**kw)
return is_ok
def fixConsistency(self, **kw):
self.log("Update cron : %s" % self.configuration_file_path)
if os.path.exists(self.configuration_file_path):
shutil.rmtree(self.configuration_file_path)
create(path=self.configuration_file_path,
text=self._getCronTemplate())
return self.checkConsistency(fixit=0, **kw)
* hard nproc 8096
* soft nproc 1024
* hard nofile 32768
* soft nofile 32768
root hard nofile 65535
root soft nofile 65535
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import ConfigParser
import os
import time
import traceback
import tempfile
import datetime
import shutil
from slapos.networkcachehelper import NetworkcacheClient, \
helper_download_network_cached
class NetworkCache:
def __init__(self, configuration_path):
if not os.path.exists(configuration_path):
raise ValueError("You need configuration file")
self.configuration = configuration_path
self._load()
def _load(self):
network_cache_info = ConfigParser.RawConfigParser()
network_cache_info.read(self.configuration)
network_cache_info_dict = dict(network_cache_info.items('networkcache'))
def get_(name):
return network_cache_info_dict.get(name)
self.download_binary_cache_url = get_('download-binary-cache-url')
self.download_cache_url = get_('download-cache-url')
self.download_binary_dir_url = get_('download-binary-dir-url')
self.signature_certificate_list = get_('signature-certificate-list')
# Not mandatory
self.dir_url = get_('upload-dir-url')
self.cache_url = get_('upload-cache-url')
self.signature_private_key_file = get_('signature_private_key_file')
self.shacache_cert_file = get_('shacache-cert-file')
self.shacache_key_file = get_('shacache-key-file')
self.shadir_cert_file = get_('shadir-cert-file')
self.shadir_key_file = get_('shadir-key-file')
if network_cache_info.has_section('slapupdate'):
self.directory_key = network_cache_info.get('slapupdate', 'upgrade_key')
else:
self.directory_key = "slapos-upgrade-testing-key"
def upload(self, path, metadata_dict):
"""
Upload an existing file, using a file_descriptor.
"""
file_descriptor = open(path, 'r')
if not (self.dir_url and self.cache_url):
return False
# backward compatibility
metadata_dict.setdefault('file', 'notused')
metadata_dict.setdefault('urlmd5', 'notused')
# convert '' into None in order to call nc nicely
with NetworkcacheClient(self.cache_url, self.dir_url,
signature_private_key_file=self.signature_private_key_file or None,
shacache_cert_file=self.shacache_cert_file or None,
shacache_key_file=self.shacache_key_file or None,
shadir_cert_file=self.shadir_cert_file or None,
shadir_key_file=self.shadir_key_file or None,
) as nc:
return nc.upload(file_descriptor, self.directory_key, **metadata_dict)
def download(self, path, wanted_metadata_dict={},
required_key_list=[], strategy=None):
result = helper_download_network_cached(
self.download_binary_dir_url,
self.download_binary_cache_url,
self.signature_certificate_list,
self.directory_key, wanted_metadata_dict,
required_key_list, strategy)
if result:
# XXX check if nc filters signature_certificate_list!
# Creates a file with content to desired path.
file_descriptor, metadata_dict = result
f = open(path, 'w+b')
try:
shutil.copyfileobj(file_descriptor, f)
# XXX method should check MD5.
return metadata_dict
finally:
f.close()
file_descriptor.close()
return False
def strategy(entry_list):
"""Get the latest entry. """
timestamp = 0
best_entry = None
for entry in entry_list:
if entry['timestamp'] > timestamp:
best_entry = entry
timestamp = entry['timestamp']
return best_entry
def get_yes_no(prompt):
while True:
answer = raw_input(prompt + " [y,n]: ")
if answer.upper() in ['Y', 'YES']:
return True
if answer.upper() in ['N', 'NO']:
return False
class Signature:
def __init__(self, config, logger=None):
self.config = config
self.logger = logger
def log(self, message):
if self.logger is not None:
self.logger.debug(message)
else:
print message
def _download(self, path):
"""
Download a tar of the repository from cache, and untar it.
"""
shacache = NetworkCache(self.config.slapos_configuration)
if shacache.signature_certificate_list is None:
raise ValueError("You need at least one valid signature for download")
return shacache.download(path=path,
required_key_list=['timestamp'],
strategy=strategy)
def download(self):
"""
Get status information and return its path
"""
info, path = tempfile.mkstemp()
if not self._download(path) == False:
return path
else:
raise ValueError("No result from shacache")
def _upload(self, path):
"""
Creates uploads repository to cache.
"""
shacache = NetworkCache(self.config.slapos_configuration)
metadata_dict = {
# XXX: we set date from client side. It can be potentially dangerous
# as it can be badly configured.
'timestamp': time.time(),
}
try:
if shacache.upload(path=path,
metadata_dict=metadata_dict):
self.log('Uploaded update file to cache.')
except Exception:
self.log('Unable to upload to cache:\n%s.' % traceback.format_exc())
def upload(self, dry_run=0, verbose=1):
upgrade_info = ConfigParser.RawConfigParser()
upgrade_info.read(self.config.upgrade_file)
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
if self.config.reboot:
upgrade_info.set('system', 'reboot', tomorrow.isoformat())
if self.config.upgrade:
upgrade_info.set('system', 'upgrade', tomorrow.isoformat())
file = open(self.config.upgrade_file, "w")
upgrade_info.write(file)
file.close()
if verbose:
self.log(" You will update this :")
self.log(open(self.config.upgrade_file).read())
if dry_run:
return
if get_yes_no("Do you want to continue? "):
self._upload(self.config.upgrade_file)
def update(self, reboot=None, upgrade=None):
if reboot is None and upgrade is None:
return
if not self.current_state.has_section('system'):
self.current_state.add_section('system')
if reboot is not None:
self.current_state.set('system', 'reboot', reboot)
if upgrade is not None:
self.current_state.set('system', 'upgrade', upgrade)
current_state_file = open(self.config.srv_file, "w")
self.current_state.write(current_state_file)
current_state_file.close()
def get_signature_dict(self):
""" Convert Next state info into a dict """
map_dict = {}
for key in self.next_state.sections():
if key == "system":
continue
def clean_list(l):
return [x.strip() for x in l.split('\n') if x.strip() != '']
map_dict[key] = {}
for entry in self.next_state.options(key):
map_dict[key][entry] = clean_list(self.next_state.get(key, entry))
return map_dict
def _read_state(self, state, name):
""" Extract information from config file """
if not state.has_section('system'):
return None
return datetime.datetime.strptime(
state.get('system', name), "%Y-%m-%d").date()
def load(self):
"""
Extract information from config file and server file
"""
self.current_state = ConfigParser.RawConfigParser()
self.current_state.read(self.config.srv_file)
self.next_state = ConfigParser.ConfigParser()
self.next_state.read(self.download())
self.reboot = self._read_state(self.next_state, "reboot")
self.upgrade = self._read_state(self.next_state, "upgrade")
self.last_reboot = self._read_state(self.current_state, "reboot")
self.last_upgrade = self._read_state(self.current_state, "upgrade")
[slapupdate]
upgrade_key = '%(upgrade_key)s'
[networkcache]
download-binary-cache-url = http://www.shacache.org/shacache
download-cache-url = https://www.shacache.org/shacache
download-binary-dir-url = http://www.shacache.org/shadir
# Standard Signature handled by SlapOS Administrators
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB8DCCAVmgAwIBAgIJAPFf61p8y809MA0GCSqGSIb3DQEBBQUAMBAxDjAMBgNV
BAMMBUNPTVAtMCAXDTE0MDIxNzE2NDgxN1oYDzIxMTQwMTI0MTY0ODE3WjAQMQ4w
DAYDVQQDDAVDT01QLTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsiqCyuv1
HO9FmtwnMbEa1/u8Dn7T0k7hVKYXVQYof+59Ltbb3cA3nLjFSJDr/wQT6N89MccS
PneRzkWqZKL06Kmj+N+XJfRyVaTz1qQtNzjdbYkO6RgQq+fvq2CO0+PSnL6NttLU
/a9nQMcVm7wZ8kmY+AG5LbVo8lmxDD16Wq0CAwEAAaNQME4wHQYDVR0OBBYEFEVi
YyWHF3W7/O4NaTjn4lElLpp7MB8GA1UdIwQYMBaAFEViYyWHF3W7/O4NaTjn4lEl
Lpp7MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgIPGoxhUa16AgjZx
Jr1kUrs8Fg3ig8eRFQlBSLYfANIUxcQ2ScFAkmsvwXY3Md7uaSvMJsEl2jcjdmdi
eSreNkx85j9GtMLY/2cv0kF4yAQNRtibtDkbg6fRNkmUopDosJNVf79l1GKX8JFL
zZBOFdOaLYY/6dLRwiTUKHU6su8=
-----END CERTIFICATE-----
# BEWARE: This file will be automatically regenerated on every run of
# slappkg
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin:/usr/local/bin
MAILTO=root
# This file expects that
0 1 * * * root slappkg-update --self-update --slapos-configuration=%(configuration_path)s -v >> %(slapos_location)s/log/slappkg-update.log 2>&1
10 * * * * root slappkg-update --wait --slapos-configuration=%(configuration_path)s -v >> %(slapos_location)s/log/slappkg-update.log 2>&1
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
def _fake_call(self, *args, **kw):
self.last_call = (args, kw)
CONFIGURATION_FILE = """
[networkcache]
download-binary-cache-url = http://www.shacache.org/shacache
download-cache-url = https://www.shacache.org/shacache
download-binary-dir-url = http://www.shacache.org/shadir
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB8DCCAVmgAwIBAgIJAPFf61p8y809MA0GCSqGSIb3DQEBBQUAMBAxDjAMBgNV
BAMMBUNPTVAtMCAXDTE0MDIxNzE2NDgxN1oYDzIxMTQwMTI0MTY0ODE3WjAQMQ4w
DAYDVQQDDAVDT01QLTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsiqCyuv1
HO9FmtwnMbEa1/u8Dn7T0k7hVKYXVQYof+59Ltbb3cA3nLjFSJDr/wQT6N89MccS
PneRzkWqZKL06Kmj+N+XJfRyVaTz1qQtNzjdbYkO6RgQq+fvq2CO0+PSnL6NttLU
/a9nQMcVm7wZ8kmY+AG5LbVo8lmxDD16Wq0CAwEAAaNQME4wHQYDVR0OBBYEFEVi
YyWHF3W7/O4NaTjn4lElLpp7MB8GA1UdIwQYMBaAFEViYyWHF3W7/O4NaTjn4lEl
Lpp7MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgIPGoxhUa16AgjZx
Jr1kUrs8Fg3ig8eRFQlBSLYfANIUxcQ2ScFAkmsvwXY3Md7uaSvMJsEl2jcjdmdi
eSreNkx85j9GtMLY/2cv0kF4yAQNRtibtDkbg6fRNkmUopDosJNVf79l1GKX8JFL
zZBOFdOaLYY/6dLRwiTUKHU6su8=
-----END CERTIFICATE-----
[slapupdate]
upgrade_key = slapos-upgrade-testing-key-with-config-file
"""
UPGRADE_KEY = """[debian-default]
repository-list =
main = http://ftp.fr.debian.org/debian/ wheezy main
main-src = http://ftp.fr.debian.org/debian/ wheezy main
update = http://ftp.fr.debian.org/debian/ wheezy-updates main
update-src = http://ftp.fr.debian.org/debian/ wheezy-updates main
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi:/branches:/home:/VIFIBnexedi/Debian_7.0/ ./
re6stnet = http://git.erp5.org/dist/deb ./
key-list =
slapos = http://git.erp5.org/gitweb/slapos.package.git/blob_plain/HEAD:/debian-preseed/slapos.openbuildservice.key
re6st = http://git.erp5.org/gitweb/slapos.package.git/blob_plain/HEAD:/debian-preseed/git.erp5.org.key
filter-package-list =
ntp
openvpn
slapos.node
re6stnet
filter-promise-list =
core
signature-list =
debian+++jessie/sid+++
debian+++7.4+++
debian+++7.5+++
debian+++7.3+++
debian+++7+++
[opensuse-legacy]
repository-list =
suse = http://download.opensuse.org/distribution/12.1/repo/oss/
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi:/branches:/home:/VIFIBnexedi/openSUSE_12.1/
re6st = http://git.erp5.org/dist/rpm
key-list =
filter-promise-list =
core
filter-package-list =
ntp
openvpn
slapos.node
re6stnet
signature-list =
opensuse+++12.1+++x86_64
[system]
reboot = 2011-10-10
upgrade = 2014-06-04
"""
UPGRADE_KEY_WITHOUT_KEY_LIST = """[debian-default]
repository-list =
main = http://ftp.fr.debian.org/debian/ wheezy main
main-src = http://ftp.fr.debian.org/debian/ wheezy main
update = http://ftp.fr.debian.org/debian/ wheezy-updates main
update-src = http://ftp.fr.debian.org/debian/ wheezy-updates main
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi:/branches:/home:/VIFIBnexedi/Debian_7.0/ ./
re6stnet = http://git.erp5.org/dist/deb ./
filter-package-list =
ntp
openvpn
slapos.node
re6stnet
filter-promise-list =
core
signature-list =
debian+++jessie/sid+++
debian+++7.4+++
debian+++7.5+++
debian+++7.3+++
debian+++7+++
[opensuse-legacy]
repository-list =
suse = http://download.opensuse.org/distribution/12.1/repo/oss/
slapos = http://download.opensuse.org/repositories/home:/VIFIBnexedi:/branches:/home:/VIFIBnexedi/openSUSE_12.1/
re6st = http://git.erp5.org/dist/rpm
filter-promise-list =
core
filter-package-list =
ntp
openvpn
slapos.node
re6stnet
signature-list =
opensuse+++12.1+++x86_64
[system]
reboot = 2011-10-10
upgrade = 2014-06-04
"""
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.package.promise import hostname
import os
import unittest
def _fake_call(self, *args, **kw):
self.last_call = (args, kw)
class testPromiseHostnameCase(unittest.TestCase):
def setUp(self):
hostname.Promise._call = _fake_call
def testHostnameCheckConsistency(self):
promise = hostname.Promise()
promise.configuration_file_path = "/tmp/hostname_for_test"
self.assertFalse(promise.checkConsistency(computer_id="TESTING"))
def testHostnameFixConsistency(self):
hostname.Promise._call = _fake_call
promise = hostname.Promise()
promise.configuration_file_path = "/tmp/hostname_for_test_fix"
if os.path.exists(promise.configuration_file_path):
os.remove(promise.configuration_file_path)
self.assertFalse(promise.checkConsistency(computer_id="TESTING"))
self.assertTrue(promise.fixConsistency(computer_id="TESTING"))
self.assertEqual(promise.last_call,
((['hostname', '-F', '/tmp/hostname_for_test_fix'],), {})
)
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.package.promise import limitconf
import os
import pkg_resources
import unittest
def _fake_call(self, *args, **kw):
self.last_call = (args, kw)
class testLimitConfTestCase(unittest.TestCase):
def setUp(self):
limitconf.Promise._call = _fake_call
if os.path.exists("/tmp/test_promise_testing_limits.conf"):
os.remove("/tmp/test_promise_testing_limits.conf")
def testLimitConfCheckConsistency(self):
promise = limitconf.Promise()
promise.configuration_file_path = "/tmp/test_promise_testing_limits.conf"
self.assertFalse(promise.checkConsistency())
open(promise.configuration_file_path, "w").write("# Something")
self.assertFalse(promise.checkConsistency())
def testLimitConfFixConsistency(self):
limitconf.Promise._call = _fake_call
promise = limitconf.Promise()
promise.configuration_file_path = "/tmp/test_promise_testing_limits.conf"
self.assertFalse(promise.checkConsistency())
self.assertTrue(promise.fixConsistency())
self.assertTrue(promise.checkConsistency())
self.assertTrue(os.path.exists(promise.configuration_file_path))
limit_content = open(promise.configuration_file_path, "r").read()
self.assertEquals(limit_content, pkg_resources.resource_stream(limitconf.__name__,
'template/limits.conf.in').read())
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment