Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.toolbox
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Rafael Monnerat
slapos.toolbox
Commits
570d0dea
Commit
570d0dea
authored
Jul 25, 2016
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove slapos.builder and slapos.monitor as it only contains dead code.
parent
8a51ab86
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
2 additions
and
1442 deletions
+2
-1442
CHANGES.txt
CHANGES.txt
+2
-2
setup.py
setup.py
+0
-5
slapos/README.builder.rst
slapos/README.builder.rst
+0
-4
slapos/builder/__init__.py
slapos/builder/__init__.py
+0
-388
slapos/builder/appliance/README.txt
slapos/builder/appliance/README.txt
+0
-1
slapos/builder/appliance/builds_end_script.sh
slapos/builder/appliance/builds_end_script.sh
+0
-43
slapos/builder/appliance/each_boot_script.sh
slapos/builder/appliance/each_boot_script.sh
+0
-57
slapos/builder/script/slapos
slapos/builder/script/slapos
+0
-128
slapos/builder/script/slapos.service
slapos/builder/script/slapos.service
+0
-15
slapos/builder/script/slapos_firstboot
slapos/builder/script/slapos_firstboot
+0
-313
slapos/builder/template/hosts.in
slapos/builder/template/hosts.in
+0
-23
slapos/builder/template/ifcfg-br0.in
slapos/builder/template/ifcfg-br0.in
+0
-15
slapos/builder/template/slapos.cfg.in
slapos/builder/template/slapos.cfg.in
+0
-17
slapos/builder/template/sshd_config.in
slapos/builder/template/sshd_config.in
+0
-22
slapos/monitor.py
slapos/monitor.py
+0
-409
No files found.
CHANGES.txt
View file @
570d0dea
0.56 (2016-07-25)
=================
* slaprunner: remove create user at first launch, clone repository
can be done by slaprunner at startup
.
* slaprunner: remove create user at first launch, clone repository
can be done by slaprunner at startup.
* Remove slapos.builder and slapos.monitor as it only contains unused and dead code
.
0.55 (2016-03-01)
=================
...
...
setup.py
View file @
570d0dea
...
...
@@ -82,12 +82,7 @@ setup(name=name,
'pubsubserver = slapos.pubsub:main'
,
'qemu-qmp-client = slapos.qemuqmpclient:main'
,
'shacache = slapos.shacache:main'
,
'slapbuilder = slapos.builder:main'
,
'slapcontainer = slapos.container:main'
,
'slapmonitor = slapos.monitor:run_slapmonitor'
,
'slapmonitor-xml = slapos.monitor:run_slapmonitor_xml'
,
'slapos-kill = slapos.systool:kill'
,
'slapreport = slapos.monitor:run_slapreport'
,
'slaprunnertest = slapos.runner.runnertest:main'
,
'slaprunnerteststandalone = slapos.runner.runnertest:runStandaloneUnitTest'
,
'zodbpack = slapos.zodbpack:run [zodbpack]'
,
...
...
slapos/README.builder.rst
deleted
100644 → 0
View file @
8a51ab86
builder
=======
builder is a program to install a slapos image.
slapos/builder/__init__.py
deleted
100644 → 0
View file @
8a51ab86
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 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 adviced 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
sys
from
optparse
import
OptionParser
,
Option
from
subprocess
import
call
as
subprocessCall
from
stat
import
S_ISBLK
,
ST_MODE
from
tempfile
import
mkdtemp
,
mkstemp
import
shutil
import
pkg_resources
class
SlapError
(
Exception
):
"""
Slap error
"""
def
__init__
(
self
,
message
):
self
.
msg
=
message
class
UsageError
(
SlapError
):
pass
class
ExecError
(
SlapError
):
pass
def
rootRightsNeeded
(
func
):
"Decorator for permissions checking"
def
wrapped
(
*
args
,
**
kwargs
):
if
os
.
getuid
()
!=
0
:
raise
UsageError
(
"You need to be root to run this script !"
)
return
func
(
*
args
,
**
kwargs
)
return
wrapped
def
_call
(
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
"""
print
"Calling: %s"
%
' '
.
join
(
cmd_args
)
if
not
dry_run
:
try
:
if
subprocessCall
(
cmd_args
,
stdout
=
stdout
,
stderr
=
stderr
)
!=
0
:
raise
ValueError
(
'Issues during running %r'
%
cmd_args
)
except
OSError
as
e
:
raise
ExecError
(
'Process respond:"%s" when calling "%s"'
%
\
(
str
(
e
),
' '
.
join
(
cmd_args
)))
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
(
"-c"
,
"--slapos_configuration"
,
help
=
"The path of the slapos configuration directory"
,
default
=
'/etc/slapos/'
,
type
=
str
),
Option
(
"-o"
,
"--hostname_path"
,
help
=
"The hostname configuration path"
,
default
=
'/etc/HOSTNAME'
,
type
=
str
),
Option
(
"-s"
,
"--host_path"
,
help
=
"The hosts configuration path"
,
default
=
'/etc/hosts'
,
type
=
str
),
Option
(
"-n"
,
"--dry_run"
,
help
=
"Simulate the execution steps"
,
default
=
False
,
action
=
"store_true"
),
Option
(
None
,
"--no_usb"
,
default
=
False
,
action
=
"store_true"
,
help
=
"Do not write on USB."
),
Option
(
None
,
"--one_disk"
,
default
=
False
,
action
=
"store_true"
,
help
=
"Prepare image for one disk usage"
),
Option
(
None
,
"--virtual"
,
default
=
False
,
action
=
"store_true"
,
help
=
"Work with .vmdk files"
)
])
def
check_args
(
self
):
"""
Check arguments
"""
(
options
,
args
)
=
self
.
parse_args
()
if
len
(
args
)
!=
8
:
self
.
error
(
"Incorrect number of arguments"
)
system_path
,
device_path
,
computer_id
,
key_path
,
master_url
,
\
slapos_software_profile_url
,
cert_file
,
key_file
=
args
system_path
=
os
.
path
.
abspath
(
system_path
)
if
not
os
.
path
.
isfile
(
system_path
):
self
.
error
(
"%s isn't valid. The first argument must be the raw "
\
"slapos file"
%
system_path
)
if
options
.
virtual
:
options
.
no_usb
=
True
options
.
one_disk
=
True
device_path
=
os
.
path
.
abspath
(
device_path
)
if
not
options
.
no_usb
:
mode
=
os
.
stat
(
device_path
)[
ST_MODE
]
if
not
S_ISBLK
(
mode
):
self
.
error
(
"%s isn't a valid block file. Please enter as second "
\
"argument a valid block file for the raw to be copied on "
\
"it"
%
device_path
)
if
not
os
.
path
.
isfile
(
key_path
):
self
.
error
(
"%r file not found"
%
key_path
)
return
options
,
system_path
,
device_path
,
computer_id
,
key_path
,
\
master_url
,
slapos_software_profile_url
,
cert_file
,
key_file
@
rootRightsNeeded
def
run
(
config
):
dry_run
=
config
.
dry_run
print
"Creating temp directory"
if
not
dry_run
:
mount_dir_path
=
mkdtemp
()
fdisk_output_path
=
mkstemp
()[
1
]
else
:
mount_dir_path
=
"/tmp/a_generated_directory"
fdisk_output_path
=
"/tmp/a_generated_file"
try
:
if
not
config
.
virtual
:
offset
=
0
fdisk_output_file
=
open
(
fdisk_output_path
,
'w'
)
_call
([
'sfdisk'
,
'-d'
,
'-uS'
,
config
.
system_path
],
stdout
=
fdisk_output_file
)
fdisk_output_file
.
close
()
fdisk_output_file
=
open
(
fdisk_output_path
,
'r'
)
for
line
in
fdisk_output_file
:
line
=
line
.
rstrip
().
replace
(
' '
,
''
)
if
line
.
endswith
(
"bootable"
):
offset
=
int
(
line
.
split
(
':'
)[
1
].
split
(
','
)[
0
].
split
(
'='
)[
1
])
fdisk_output_file
.
close
()
offset
=
offset
*
512
_call
([
'mount'
,
'-o'
,
'loop,offset=%i'
%
offset
,
config
.
system_path
,
mount_dir_path
],
dry_run
=
dry_run
)
# Call vmware-mount to mount Virtual disk image
else
:
print
"Mount Virtual Image"
fdisk_output_file
=
open
(
fdisk_output_path
,
'w'
)
_call
([
'vmware-mount'
,
config
.
system_path
,
mount_dir_path
],
dry_run
=
dry_run
)
try
:
# Create slapos configuration directory if needed
slap_configuration_directory
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
config
.
slapos_configuration
]))
slap_configuration_file
=
os
.
path
.
normpath
(
'/'
.
join
([
slap_configuration_directory
,
'slapos.cfg'
]))
if
not
os
.
path
.
exists
(
slap_configuration_directory
):
print
"Creating directory: %s"
%
slap_configuration_directory
if
not
dry_run
:
os
.
mkdir
(
slap_configuration_directory
,
0711
)
certificate_repository_path
=
os
.
path
.
join
(
'/opt/slapos/pki'
)
key_file
=
os
.
path
.
join
(
config
.
slapos_configuration
,
'computer.key'
)
cert_file
=
os
.
path
.
join
(
config
.
slapos_configuration
,
'computer.crt'
)
key_file_dest
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
key_file
]))
cert_file_dest
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
cert_file
]))
for
(
src
,
dst
)
in
[(
config
.
key_file
,
key_file_dest
),
(
config
.
cert_file
,
cert_file_dest
)]:
print
"Coping %r to %r, and setting minimal privileges"
%
(
src
,
dst
)
if
not
dry_run
:
shutil
.
copy
(
src
,
dst
)
os
.
chmod
(
dst
,
0600
)
os
.
chown
(
dst
,
0
,
0
)
# Put slapgrid configuration file
print
"Creating slap configuration: %s"
%
slap_configuration_file
if
not
dry_run
:
open
(
slap_configuration_file
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'template/slapos.cfg.in'
).
read
()
%
dict
(
computer_id
=
config
.
computer_id
,
master_url
=
config
.
master_url
,
key_file
=
key_file
,
cert_file
=
cert_file
,
certificate_repository_path
=
certificate_repository_path
))
hostname_path
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
config
.
hostname_path
]))
print
"Setting hostname in : %s"
%
hostname_path
if
not
dry_run
:
open
(
hostname_path
,
'w'
).
write
(
"%s
\
n
"
%
config
.
computer_id
)
# Adding the hostname as a valid address
host_path
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
config
.
host_path
]))
print
"Creating %r"
%
host_path
if
not
dry_run
:
open
(
host_path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'template/hosts.in'
).
read
()
%
dict
(
computer_id
=
config
.
computer_id
))
# Creating safe sshd_config
sshd_path
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
'etc'
,
'ssh'
,
'sshd_config'
]))
print
"Creating %r"
%
sshd_path
if
not
dry_run
:
open
(
sshd_path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'template/sshd_config.in'
).
read
())
os
.
chmod
(
sshd_path
,
0600
)
# Creating default bridge config
br0_path
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
'etc'
,
'sysconfig'
,
'network'
,
'ifcfg-br0'
]))
print
"Creating %r"
%
br0_path
if
not
dry_run
:
open
(
br0_path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'template/ifcfg-br0.in'
).
read
())
# Writing ssh key
user_path
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
'root'
]))
ssh_key_directory
=
os
.
path
.
normpath
(
'/'
.
join
([
user_path
,
'.ssh'
]))
ssh_key_path
=
os
.
path
.
normpath
(
'/'
.
join
([
ssh_key_directory
,
'authorized_keys'
]))
stat_info
=
os
.
stat
(
user_path
)
uid
,
gid
=
stat_info
.
st_uid
,
stat_info
.
st_gid
ssh_key_directory
=
os
.
path
.
dirname
(
ssh_key_path
)
if
not
os
.
path
.
exists
(
ssh_key_directory
):
print
"Creating ssh directory: %s"
%
ssh_key_directory
if
not
dry_run
:
os
.
mkdir
(
ssh_key_directory
)
if
not
dry_run
:
print
"Setting uid:gid of %r to %s:%s"
%
(
ssh_key_directory
,
uid
,
gid
)
os
.
chown
(
ssh_key_directory
,
uid
,
gid
)
os
.
chmod
(
ssh_key_directory
,
0700
)
print
"Creating file: %s"
%
ssh_key_path
if
not
dry_run
:
shutil
.
copyfile
(
config
.
key_path
,
ssh_key_path
)
if
not
dry_run
:
print
"Setting uid:gid of %r to %s:%s"
%
(
ssh_key_path
,
uid
,
gid
)
os
.
chown
(
ssh_key_path
,
uid
,
gid
)
os
.
chmod
(
ssh_key_path
,
0600
)
# slapos buildout profile
slapos_software_file
=
os
.
path
.
normpath
(
'/'
.
join
([
mount_dir_path
,
config
.
slapos_configuration
,
'software.cfg'
]))
print
"Creating slapos software profile: %s"
%
slapos_software_file
if
not
dry_run
:
open
(
slapos_software_file
,
'w'
).
write
(
'[buildout]
\
n
extends = %s'
%
config
.
slapos_software_profile_url
)
os
.
chmod
(
slapos_software_file
,
0644
)
# Creating boot scripts
path
=
os
.
path
.
join
(
mount_dir_path
,
'etc'
,
'slapos'
,
'slapos'
)
print
"Creating %r"
%
path
if
not
dry_run
:
open
(
path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'script/%s'
%
'slapos'
).
read
())
os
.
chmod
(
path
,
0755
)
path
=
os
.
path
.
join
(
mount_dir_path
,
'etc'
,
'systemd'
,
'system'
,
'slapos.service'
)
print
"Creating %r"
%
path
if
not
dry_run
:
open
(
path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'script/%s'
%
'slapos.service'
).
read
())
os
.
chmod
(
path
,
0755
)
# Removing line in slapos script activating kvm in virtual
if
config
.
virtual
:
path
=
os
.
path
.
join
(
mount_dir_path
,
'etc'
,
'slapos'
,
'slapos'
)
_call
([
'sed'
,
'-i'
,
"$d"
,
path
],
dry_run
=
dry_run
)
_call
([
'sed'
,
'-i'
,
"$d"
,
path
],
dry_run
=
dry_run
)
# Adding slapos_firstboot in case of MultiDisk usage
if
not
config
.
one_disk
:
for
script
in
[
'slapos_firstboot'
]:
path
=
os
.
path
.
join
(
mount_dir_path
,
'etc'
,
'init.d'
,
script
)
print
"Creating %r"
%
path
if
not
dry_run
:
open
(
path
,
'w'
).
write
(
pkg_resources
.
resource_stream
(
__name__
,
'script/%s'
%
script
).
read
())
os
.
chmod
(
path
,
0755
)
else
:
for
script
in
[
'slapos_firstboot'
]:
path
=
os
.
path
.
join
(
mount_dir_path
,
'etc'
,
'init.d'
,
script
)
if
os
.
path
.
exists
(
path
):
print
"Removing %r"
%
path
os
.
remove
(
path
)
finally
:
if
not
config
.
virtual
:
_call
([
'umount'
,
mount_dir_path
],
dry_run
=
dry_run
)
else
:
print
"Umount Virtual Machine"
_call
([
"vmware-mount"
,
"-K"
,
config
.
system_path
],
dry_run
=
dry_run
)
finally
:
# Always delete temporary directory
#print "No deleting"
print
"Deleting temp directory: %s"
%
mount_dir_path
if
not
dry_run
:
shutil
.
rmtree
(
mount_dir_path
)
print
"Deleting temp file: %s"
%
fdisk_output_path
if
not
dry_run
:
os
.
remove
(
fdisk_output_path
)
# Copying
if
not
config
.
no_usb
:
print
"
\
n
Starting the copy of the raw file, it may take some time...
\
n
"
_call
([
'dd'
,
"if=%s"
%
config
.
system_path
,
"of=%s"
%
config
.
device_path
],
dry_run
=
dry_run
)
_call
([
'sync'
])
print
"
\
n
... copy finished! You may now take the usb key back."
return
0
class
Config
:
def
setConfig
(
self
,
option_dict
,
system_path
,
device_path
,
computer_id
,
key_path
,
master_url
,
slapos_software_profile_url
,
cert_file
,
key_file
):
"""
Set options given by parameters.
"""
# Set options parameters
for
option
,
value
in
option_dict
.
__dict__
.
items
():
setattr
(
self
,
option
,
value
)
self
.
system_path
=
system_path
self
.
device_path
=
device_path
self
.
computer_id
=
computer_id
self
.
key_path
=
key_path
self
.
master_url
=
master_url
self
.
slapos_software_profile_url
=
slapos_software_profile_url
self
.
key_file
=
key_file
self
.
cert_file
=
cert_file
def
main
():
"Run default configuration."
usage
=
"usage: %s [options] SYSTEM_FILE OUTPUT_DEVICE "
\
"COMPUTER_ID SSH_KEY_FILE MASTER_URL SLAPOS_SOFTWARE_PROFILE_URL "
\
"COMPUTER_CERTIFICATE COMPUTER_KEY"
%
sys
.
argv
[
0
]
try
:
# Parse arguments
config
=
Config
()
config
.
setConfig
(
*
Parser
(
usage
=
usage
).
check_args
())
run
(
config
)
return_code
=
0
except
UsageError
,
err
:
print
>>
sys
.
stderr
,
err
.
msg
print
>>
sys
.
stderr
,
"For help use --help"
return_code
=
16
except
ExecError
,
err
:
print
>>
sys
.
stderr
,
err
.
msg
return_code
=
16
except
SystemExit
,
err
:
# Catch exception raise by optparse
return_code
=
err
sys
.
exit
(
return_code
)
slapos/builder/appliance/README.txt
deleted
100644 → 0
View file @
8a51ab86
Mirror of files from http://susestudio.com/appliance/
slapos/builder/appliance/builds_end_script.sh
deleted
100644 → 0
View file @
8a51ab86
#!/bin/bash
##############################################################################
#
# Copyright (c) 2010 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.
#
##############################################################################
#
# This script is executed at the end of appliance creation. Here you can do
# one-time actions to modify your appliance before it is ever used, like
# removing files and directories to make it smaller, creating symlinks,
# generating indexes, etc.
#
# The 'kiwi_type' variable will contain the format of the appliance (oem =
# disk image, vmx = VMware, iso = CD/DVD, xen = Xen).
#
# read in some variables
.
/studio/profile
# Removing eth0 config file which became unecessary with the bridge creation
rm
-f
/etc/sysconfig/network/ifcfg-eth0
slapos/builder/appliance/each_boot_script.sh
deleted
100644 → 0
View file @
8a51ab86
#!/bin/bash
### BEGIN INIT INFO
# Provides: suse_studio_custom
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Description: Script run whenever the appliance boots
### END INIT INFO
##############################################################################
#
# Copyright (c) 2010 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.
#
##############################################################################
#
# This script is executed whenever your appliance boots. Here you can add
# commands to be executed before the system enters the first runlevel. This
# could include loading kernel modules, starting daemons that aren't managed
# by init files, asking questions at the console, etc.
#
# The 'kiwi_type' variable will contain the format of the appliance (oem =
# disk image, vmx = VMware, iso = CD/DVD, xen = Xen).
#
#
# read in some variables
.
/studio/profile
if
[
-f
/etc/init.d/suse_studio_firstboot
]
then
echo
"______________Init of SlapOS service_______________"
/etc/init.d/slapos_firstboot
systemctl
enable
slapos.service
systemctl start slapos.service
elif
[
-f
/token_second_boot
]
;
then
/etc/init.d/slapos_secondboot
fi
slapos/builder/script/slapos
deleted
100755 → 0
View file @
8a51ab86
#!/bin/sh
##############################################################################
#
# Copyright (c) 2010 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.
#
##############################################################################
# clean the system
for
service
in
rpcbind network-remotefs postfix
;
do
chkconfig
--del
$service
/etc/init.d/
$service
stop
done
IPV6CHECK
=
ipv6.google.com
# Test ipv6 connectivity and if not working use openvpn
# and wait for it to be ready
/etc/init.d/openvpn stop
ping6
-c
2
$IPV6CHECK
if
[[
$?
!=
0
]]
;
then
echo
""" Starting openVPN """
/etc/init.d/openvpn start
ping6
-c
2
$IPV6CHECK
while
[[
$?
!=
0
]]
;
do
ping6
-c
2
$IPV6CHECK
done
# Ask slapos to use openvpn as ipv6 provider
if
[
!
-f
/etc/slapos/openvpn-needed
]
;
then
touch
/etc/slapos/openvpn-needed
echo
"ipv6_interface = tapVPN"
>>
/etc/slapos/slapos.cfg
fi
else
# OpenVPN not needed delete last line of slapos.cfg if OpenVPN has been used before
if
[
-f
/etc/slapos/openvpn-needed
]
;
then
rm
/etc/slapos/openvpn-needed
sed
-i
'$d'
/etc/slapos/slapos.cfg
fi
fi
# set random root password
pwgen
-sync
512 1 | passwd
--stdin
root
SLAP_INSTALL_LOG
=
/opt/slapos/slapos-install.log
while
:
;
do
if
[
-f
/opt/slapos/bin/slapformat
]
&&
[
-f
/opt/slapos/bin/bang
]
;
then
# slapos tools available, nothing to do
break
fi
# software not detected, force forever installation
echo
-n
"Installing SlapOS, log availble at
${
SLAP_INSTALL_LOG
}
..."
mkdir
-p
/opt/slapos
(
python
-S
-c
\
'import urllib2;print urllib2.urlopen("http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py").read()'
\
| python
-S
-
-c
/etc/slapos/software.cfg buildout:directory
=
/opt/slapos
\
>>
${
SLAP_INSTALL_LOG
}
2>&1
&&
/opt/slapos/bin/buildout
-c
\
/etc/slapos/software.cfg buildout:directory
=
/opt/slapos
>>
\
${
SLAP_INSTALL_LOG
}
2>&1
)
&&
(
echo
"done."
)
||
(
echo
\
"failed, retrying, the last error was:."
;
tail
-n
20
${
SLAP_INSTALL_LOG
}
;
rm
-f
/opt/slapos/bin/slapformat
)
done
# Create PKI repository
repo
=
`
egrep ^certificate_repository_path /etc/slapos/slapos.cfg |
sed
's/^certificate_repository_path.*= *//'
`
mkdir
-v
-p
-m
0755
$repo
# software detected, ready to run
# Set up cron
echo
"""# BEWARE: This file will be automatically regenerated on each boot
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
0 0 * * * root /opt/slapos/bin/slapformat --verbose --log_file=/opt/slapos/slapformat.log /etc/slapos/slapos.cfg >> /opt/slapos/slapformat.log 2>&1
*/5 * * * * root /opt/slapos/bin/slapgrid-cp --verbose --logfile=/opt/slapos/slapgrid-cp.log --pidfile=/opt/slapos/slapgrid-cp.pid /etc/slapos/slapos.cfg >> /opt/slapos/slapgrid-cp.log 2>&1
*/5 * * * * root /opt/slapos/bin/slapgrid-sr --verbose --logfile=/opt/slapos/slapgrid-sr.log --pidfile=/opt/slapos/slapgrid-sr.pid /etc/slapos/slapos.cfg >> /opt/slapos/slapgrid-sr.log 2>&1
0 0 * * * root /opt/slapos/bin/slapgrid-ur --verbose --logfile=/opt/slapos/slapgrid-ur.log --pidfile=/opt/slapos/slapgrid-ur.pid /etc/slapos/slapos.cfg >> /opt/slapos/slapgrid-ur.log 2>&1
"""
>
/etc/cron.d/slapos
# Setup more server like network parameters in order to avoid
# "Neighbour table overflow."
# Those machines are itself has a lot of interfaces and are in
# heavily networked environment, so limit of ARP cache for IPv4
# and IPv6 is 4x higher then default
# More tuning can be applied from: http://www.enigma.id.au/linux_tuning.txt
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
# Execute slapformat
echo
-n
"Running slapformat..."
/opt/slapos/bin/slapformat
--verbose
--console
/etc/slapos/slapos.cfg
echo
"done."
echo
-n
"Banging..."
/opt/slapos/bin/bang
-m
"Rebooted"
/etc/slapos/slapos.cfg
echo
"done."
# Enable noop scheduler for disk which have SLAPOS labeled partition
disk
=
`
blkid
-L
SLAPOS |
sed
-r
-e
's/(\/dev\/|[0-9]*$)//g'
`
echo
noop
>
/sys/block/
$disk
/queue/scheduler
# Set kvm up
modprobe kvm_intel
chmod
666 /dev/kvm
\ No newline at end of file
slapos/builder/script/slapos.service
deleted
100644 → 0
View file @
8a51ab86
[Unit]
Description=SlapOs Boot script
Requires=basic.target
Wants=network.target remote-fs.target
After=basic.target network.target remote-fs.target
[Service]
Type=simple
ExecStart=/etc/slapos/slapos
StandardOutput=tty
TTYPath=/dev/console
[Install]
WantedBy=multi-user.target
slapos/builder/script/slapos_firstboot
deleted
100755 → 0
View file @
8a51ab86
#!/usr/bin/python
### BEGIN INIT INFO
# Provides: slapos_firstboot
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Description: Configures first boot of SlapOS
### END INIT INFO
##############################################################################
#
# Copyright (c) 2010 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
shutil
import
subprocess
import
tempfile
import
time
# some constants
LABEL
=
"SLAPOS"
MINIMUM_FREE_SPACE_GB
=
60
MINIMUM_FREE_SPACE
=
MINIMUM_FREE_SPACE_GB
*
1024
*
1024
*
1024
SLAPOS_MARK
=
'# Added by SlapOS
\
n
'
def
callWithCheck
(
args
):
"""Calls args in subprocesses, rasies ValueError if command failed"""
if
subprocess
.
call
(
args
)
!=
0
:
raise
ValueError
def
callWithIgnore
(
args
):
"""Calls args in subprocess, ignores issues"""
subprocess
.
call
(
args
)
def
partprobe
():
"""Calls partprobe utility"""
callWithIgnore
(
"partprobe"
)
def
env
():
"""Returns language neutreal environment"""
env
=
{}
for
k
,
v
in
os
.
environ
.
iteritems
():
if
'LANG'
not
in
k
:
env
[
k
]
=
v
env
[
'LANG'
]
=
'C'
env
[
'LANGUAGE'
]
=
'C'
return
env
def
getPartitionList
(
path
):
"""Returns list of all partitions found on disk"""
partprobe
()
result
=
subprocess
.
Popen
([
'fdisk'
,
'-l'
,
path
],
env
=
env
(),
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
).
communicate
()[
0
]
partition_list
=
[]
for
l
in
result
.
split
(
'
\
n
'
):
if
l
.
startswith
(
path
):
partition_list
.
append
(
l
.
split
()[
0
])
return
partition_list
def
setupFilesystem
(
path
):
"""Setups partition on path"""
print
"Setting up filesystem on %r"
%
path
partprobe
()
callWithCheck
([
"mkfs"
,
"-m"
,
"1"
,
"-L"
,
LABEL
,
"-t"
,
"ext4"
,
path
])
partprobe
()
def
prepareDisk
(
path
):
"""Prepares disk and creates partition"""
callWithCheck
([
"parted"
,
"--script"
,
path
,
"mklabel"
,
"msdos"
])
callWithCheck
([
"parted"
,
"--script"
,
'--'
,
path
,
"mkpart"
,
"primary"
,
"ext2"
,
"0"
,
"-1"
])
partition
=
path
+
'1'
setupFilesystem
(
partition
)
def
findEmptyDisk
():
"""Tries to find not configured yet disk"""
result
=
subprocess
.
Popen
([
'parted'
,
'--script'
,
'-l'
],
env
=
env
(),
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
STDOUT
).
communicate
()[
0
]
for
line
in
result
.
split
(
'
\
n
'
):
if
'unrecognised disk label'
in
line
:
disk
=
line
.
split
(
':'
)[
1
].
strip
()
fdisk
=
subprocess
.
Popen
([
'fdisk'
,
'-l'
,
disk
],
env
=
env
(),
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
STDOUT
).
communicate
()[
0
]
size
=
0
for
l
in
fdisk
.
split
(
'
\
n
'
):
if
l
.
startswith
(
'Disk %s:'
%
disk
):
size
=
int
(
l
.
split
(
' '
)[
4
])
break
if
size
>
MINIMUM_FREE_SPACE
:
return
disk
def
deactivateSwap
():
"""Disactivates swap in /etc/fstab and turns off any existing"""
old_fstab
=
open
(
'/etc/fstab'
,
'r'
).
readlines
()
fstab
=
open
(
'/etc/fstab'
,
'w'
)
for
line
in
old_fstab
:
if
'swap'
in
line
:
line
=
'#deactivated by slapos#'
+
line
fstab
.
write
(
line
)
fstab
.
close
()
callWithIgnore
([
'swapoff'
,
'-a'
])
def
prepareSlapOSPartition
(
mount_point
):
"""Prepare SlapOS partitioning"""
new_fstab
=
open
(
'/etc/fstab'
,
'r'
).
readlines
()
a
=
new_fstab
.
append
d
=
dict
(
label
=
LABEL
)
a
(
SLAPOS_MARK
)
a
(
'LABEL=%(label)s /mnt/%(label)s ext4 defaults,noatime 0 0
\
n
'
%
d
)
a
(
"/mnt/%(label)s/opt /opt none bind 0 0
\
n
"
%
d
)
a
(
"/mnt/%(label)s/tmp /tmp none bind 0 0
\
n
"
%
d
)
a
(
"/mnt/%(label)s/srv /srv none bind 0 0
\
n
"
%
d
)
open
(
'/etc/fstab'
,
'w'
).
write
(
''
.
join
(
new_fstab
))
partprobe
()
retry
=
10
while
True
:
try
:
print
'Trying to mount new partition, %s to go.'
%
retry
callWithCheck
([
'mount'
,
'/mnt/'
+
LABEL
])
except
ValueError
:
if
retry
>
0
:
retry
-=
1
# give some time
time
.
sleep
(
2
)
else
:
raise
else
:
break
for
d
in
[
'opt'
,
'srv'
,
'tmp'
]:
p
=
'/mnt/'
+
LABEL
+
'/'
+
d
if
not
os
.
path
.
exists
(
p
):
os
.
mkdir
(
p
)
os
.
chmod
(
p
,
0755
)
os
.
chmod
(
'/mnt/'
+
LABEL
+
'/tmp'
,
01777
)
callWithCheck
([
'mount'
,
'/opt'
])
callWithCheck
([
'mount'
,
'/tmp'
])
callWithCheck
([
'mount'
,
'/srv'
])
def
configureNtp
():
"""Configures NTP daemon"""
server
=
"server pool.ntp.org"
old_ntp
=
open
(
'/etc/ntp.conf'
,
'r'
).
readlines
()
new_ntp
=
open
(
'/etc/ntp.conf'
,
'w'
)
for
line
in
old_ntp
:
if
line
.
startswith
(
'server'
):
continue
new_ntp
.
write
(
line
)
new_ntp
.
write
(
SLAPOS_MARK
)
new_ntp
.
write
(
server
+
'
\
n
'
)
new_ntp
.
close
()
callWithIgnore
([
'chkconfig'
,
'--add'
,
'ntp'
])
def
getMountedPartitionList
():
partition_list
=
[]
for
line
in
open
(
'/etc/mtab'
,
'r'
).
readlines
():
if
line
.
startswith
(
'/dev'
):
partition_list
.
append
(
line
.
split
(
' '
)[
0
])
return
partition_list
def
getWidestFreeSpaceList
(
disk_dict
):
free_space_disk_dict
=
{}
for
disk
in
disk_dict
.
iterkeys
():
v
=
disk_dict
[
disk
]
for
l
in
v
:
size
=
int
(
l
.
split
(
':'
)[
3
].
rstrip
(
'B'
))
free_space_disk_dict
.
setdefault
(
size
,
[])
free_space_disk_dict
[
size
].
append
(
dict
(
disk
=
disk
,
info
=
l
))
if
free_space_disk_dict
:
m
=
max
(
free_space_disk_dict
)
if
m
>
MINIMUM_FREE_SPACE
:
return
free_space_disk_dict
[
max
(
free_space_disk_dict
)]
return
[]
def
findAndPrepareFreeSpace
():
"""Finds free space, ignoring / mounted device
Prefers disk with correct empty partition table"""
mounted_partition_list
=
getMountedPartitionList
()
disk_dict
=
{}
parted
=
subprocess
.
Popen
([
'parted'
,
'--script'
,
'-lm'
],
env
=
env
(),
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
).
communicate
()[
0
]
for
line
in
parted
.
split
(
'
\
n
'
):
line
=
line
.
strip
()
if
line
.
startswith
(
'/dev'
):
disk
=
line
.
split
(
':'
)[
0
]
if
any
([
q
.
startswith
(
disk
)
for
q
in
mounted_partition_list
]):
continue
# disk found, time to fetch free space
disk_dict
[
disk
]
=
[]
free
=
subprocess
.
Popen
([
'parted'
,
'--script'
,
'-m'
,
disk
,
'unit'
,
'B'
,
'print'
,
'free'
],
env
=
env
(),
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
).
communicate
()[
0
]
for
f
in
free
.
split
(
'
\
n
'
):
if
':free;'
in
f
:
disk_dict
[
disk
].
append
(
f
.
strip
())
disk_space_list
=
getWidestFreeSpaceList
(
disk_dict
)
if
len
(
disk_space_list
)
==
0
:
raise
ValueError
(
'Minumum of free space %sGB not found'
%
MINIMUM_FREE_SPACE_GB
)
disk
=
disk_space_list
[
0
]
beg
=
disk
[
'info'
].
split
(
':'
)[
1
].
rstrip
(
'B'
)
end
=
disk
[
'info'
].
split
(
':'
)[
2
].
rstrip
(
'B'
)
before
=
getPartitionList
(
disk
[
'disk'
])
callWithCheck
([
'parted'
,
'--script'
,
'-m'
,
'-a'
,
'optimal'
,
'--'
,
disk
[
'disk'
],
'unit'
,
'B'
,
'mkpart'
,
'primary'
,
'ext2'
,
beg
,
end
])
after
=
getPartitionList
(
disk
[
'disk'
])
new
=
[
q
for
q
in
after
if
q
not
in
before
]
setupFilesystem
(
new
[
0
])
return
disk
[
'disk'
]
def
configureGrub
(
mount_point
,
slapos_label_file
):
"""Configures grub on mount_point using disk"""
boot
=
os
.
path
.
join
(
mount_point
,
'boot'
)
grub
=
os
.
path
.
join
(
boot
,
'grub'
)
if
not
os
.
path
.
exists
(
boot
):
os
.
mkdir
(
boot
)
if
os
.
path
.
exists
(
grub
):
shutil
.
rmtree
(
grub
)
shutil
.
copytree
(
'/boot/grub'
,
grub
)
open
(
os
.
path
.
join
(
grub
,
'menu.lst'
),
'w'
).
write
(
"""timeout 3600
title SlapOS Error: The USB key is not first and bootable device
root (hd0,1)
chainloader +1
title Solution: Put the USB key
root (hd0,1)
chainloader +1
title Solution: Configure BIOS -- boot from USB key
root (hd0,1)
chainloader +1
title Solution: Configure BIOS -- USB key as first device
root (hd0,1)
chainloader +1
"""
)
new_map_path
=
tempfile
.
mkstemp
()[
1
]
new_map
=
open
(
new_map_path
,
'w'
)
disk
=
os
.
path
.
realpath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
slapos_label_file
),
os
.
readlink
(
slapos_label_file
)))
# this represents /dev/sdXN, so simply let's remove all possible numbers
# from right
# Note: This method's perfectioness is same as rest in this script, high
# dependency on system configuration
disk
=
disk
.
rstrip
(
'0123456789'
)
new_map
.
write
(
open
(
'/boot/grub/device.map'
).
read
()
+
'
\
n
(hd1) %s'
%
disk
)
new_map
.
close
()
grub_install
=
subprocess
.
Popen
([
'grub'
,
'--batch'
,
'--device-map=%s'
%
new_map
],
stdin
=
subprocess
.
PIPE
)
grub_install
.
communicate
(
"""root (hd1,0)
setup (hd1)
quit
"""
)
os
.
unlink
(
new_map_path
)
if
grub_install
.
returncode
is
None
or
grub_install
.
returncode
!=
0
:
raise
ValueError
(
'Issue during grub installation'
)
def
run
():
"""Prepares machine to run SlapOS"""
print
"Running SUSE Studio first boot script..."
partprobe
()
slapos_label_file
=
'/dev/disk/by-label/'
+
LABEL
if
not
os
.
path
.
exists
(
slapos_label_file
):
empty_disk
=
findEmptyDisk
()
if
empty_disk
is
not
None
:
print
"Found empty disk %r, configuring it"
%
empty_disk
prepareDisk
(
empty_disk
)
else
:
print
"No empty disk found, trying to find the biggest possible free space"
findAndPrepareFreeSpace
()
deactivateSwap
()
mount_point
=
'/mnt/'
+
LABEL
if
not
os
.
path
.
exists
(
mount_point
):
os
.
mkdir
(
mount_point
)
os
.
chmod
(
mount_point
,
0755
)
print
'Reconfiguring fstab'
prepareSlapOSPartition
(
mount_point
)
print
"Configuring fallback grub information"
configureGrub
(
mount_point
,
slapos_label_file
)
configureNtp
()
if
__name__
==
'__main__'
:
try
:
run
()
except
:
import
traceback
sleep
=
120
print
"There was uncaught issue with SlapOS configuration"
print
"System will be restarted in %ss"
%
sleep
print
"Below traceback might be useful:"
traceback
.
print_exc
()
time
.
sleep
(
sleep
)
callWithIgnore
([
'init'
,
'6'
])
slapos/builder/template/hosts.in
deleted
100644 → 0
View file @
8a51ab86
#
# hosts This file describes a number of hostname-to-address
# mappings for the TCP/IP subsystem. It is mostly
# used at boot time, when no name servers are running.
# On small systems, this file can be used instead of a
# "named" name server.
# Syntax:
#
# IP-Address Full-Qualified-Hostname Short-Hostname
#
127.0.0.1 %(computer_id)s localhost
# special IPv6 addresses
::1 %(computer_id)s localhost ipv6-localhost ipv6-loopback
fe00::0 ipv6-localnet
ff00::0 ipv6-mcastprefix
ff02::1 ipv6-allnodes
ff02::2 ipv6-allrouters
ff02::3 ipv6-allhosts
slapos/builder/template/ifcfg-br0.in
deleted
100644 → 0
View file @
8a51ab86
BOOTPROTO='dhcp'
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth0'
BRIDGE_STP='off'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR=''
MTU=''
NAME=''
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'
USERCONTROL='no'
slapos/builder/template/slapos.cfg.in
deleted
100644 → 0
View file @
8a51ab86
[slapos]
software_root = /opt/slapgrid
instance_root = /srv/slapgrid
master_url = %(master_url)s
computer_id = %(computer_id)s
key_file = %(key_file)s
cert_file = %(cert_file)s
certificate_repository_path = %(certificate_repository_path)s
[slapformat]
computer_xml = /opt/slapos/slapos.xml
partition_amount = 100
bridge_name = br0
partition_base_name = slappart
user_base_name = slapuser
tap_base_name = slaptap
ipv4_local_network = 10.0.0.0/16
slapos/builder/template/sshd_config.in
deleted
100644 → 0
View file @
8a51ab86
PermitRootLogin yes
AllowUsers root
AddressFamily inet6
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
PasswordAuthentication no
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
Subsystem sftp /usr/lib64/ssh/sftp-server
UsePAM yes
slapos/monitor.py
deleted
100644 → 0
View file @
8a51ab86
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 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 adviced 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
import
optparse
import
os
import
sys
import
time
from
lxml
import
etree
as
ElementTree
import
sqlite3.dbapi2
as
sqlite3
import
psutil
#define global variable for log file
log_file
=
False
def
read_pid
(
path
):
with
open
(
path
,
'r'
)
as
fin
:
# pid file might contain other stuff we don't care about (ie. postgres)
pid
=
fin
.
readline
()
return
int
(
pid
)
class
MonitoringTool
(
object
):
"""Provide functions to monitor CPU and Memory"""
def
__init__
(
self
):
pass
def
get_cpu_and_memory_usage
(
self
,
proc
):
"""Return CPU and Memory usage (percent) and
the specific moment used for the measure"""
return
[
proc
.
get_cpu_percent
(),
sum
(
proc
.
get_cpu_times
()),
proc
.
get_memory_percent
(),
proc
.
get_memory_info
()[
0
],
datetime
.
datetime
.
now
()]
class
GenerateXML
(
object
):
"""Return a XML file upon request by reading from database"""
def
__init__
(
self
,
element_tree
,
path_database
,
path_xml
):
self
.
element_tree
=
element_tree
self
.
path_database
=
path_database
self
.
path_xml
=
path_xml
def
dump_xml
(
self
):
"""This func read data from database and through
_write_xml_output write result on xml file"""
consumption_infos
=
[]
#This list hold the consuption infos in the following order
#[CPU % usage, CPU time usage (seconds), Memory % usage, Memory space usage (byte), date, time]
conn
=
sqlite3
.
connect
(
self
.
path_database
)
cursor
=
conn
.
cursor
()
cursor
.
execute
(
"SELECT * FROM data"
)
for
row
in
cursor
:
consumption_infos
.
append
(
row
)
#If the database is not empty
if
consumption_infos
!=
[]:
consumption_summary
=
self
.
_eval_consumption_summary
(
consumption_infos
)
self
.
_write_xml_output
(
consumption_summary
,
self
.
path_xml
)
#Once we got infos we delete the table 'data'
cursor
.
execute
(
"DELETE FROM data"
)
conn
.
commit
()
cursor
.
close
()
conn
.
close
()
def
_eval_consumption_summary
(
self
,
consumption_infos
):
"""This function return a resources usage summary, for pricing purpose"""
memory_percentage
=
[]
memory_space
=
[]
cpu_time
=
[]
total_cpu_time
=
0.00
previous
=
0.00
first_time
=
False
#The total time that the cpu spent to work on it
#Start-end time and date
start_time
=
consumption_infos
[
0
][
5
]
end_time
=
consumption_infos
[
-
1
][
5
]
start_date
=
consumption_infos
[
0
][
4
]
end_date
=
consumption_infos
[
-
1
][
4
]
for
item
in
consumption_infos
:
cpu_time
.
append
(
item
[
1
])
memory_percentage
.
append
(
item
[
2
])
memory_space
.
append
(
item
[
3
])
#For all the samples, we calculate CPU consumption time
for
indice
,
element
in
enumerate
(
cpu_time
):
if
indice
==
0
:
first_sample
=
float
(
element
)
first_time
=
True
else
:
#If the partition has been restarted...
if
previous
>
float
(
element
):
#If the partition has been restarted for the first time...
if
first_time
:
#We count the usage before the stop
previous
=
previous
-
first_sample
first_time
=
False
total_cpu_time
=
total_cpu_time
+
previous
previous
=
float
(
element
)
#If the partition hasn't been restarted, we count only the difference between the last and the first sample
if
first_time
:
total_cpu_time
=
cpu_time
[
-
1
]
-
first_sample
#Else, we add the last sample to the total CPU consumption time
else
:
total_cpu_time
=
total_cpu_time
+
cpu_time
[
-
1
]
return
[
total_cpu_time
,
sum
(
memory_space
)
/
float
(
len
(
memory_space
)),
start_time
,
end_time
,
start_date
,
end_date
]
#return [scipy.mean(cpu_percentage), cpu_time, scipy.mean(memory_percentage),
# scipy.mean(memory_space), start_time, end_time, start_date, end_date]
def
_write_xml_output
(
self
,
res_list
,
storage_path
):
"""This function provide to dump on xml the consumption infos,
the res_list contains the following informations:
[CPU mean %, CPU whole usage (seconds), Memory mean %, Memory mean space usage (byte),
start_time, end_time, start_date, end_date]"""
#XXX- NOTE
"""The res_list has been recently changed, now it contains
[CPU whole usage (seconds), Memory mean space usage (byte)]"""
res_list
=
map
(
str
,
res_list
)
cpu_list
=
[
'CPU Consumption'
,
'CPU consumption of the partition on %s at %s'
%
(
res_list
[
5
],
res_list
[
3
]),
res_list
[
0
],
]
memory_list
=
[
'Memory consumption'
,
'Memory consumption of the partition on %s at %s'
%
(
res_list
[
5
],
res_list
[
3
]),
res_list
[
1
],
]
root
=
ElementTree
.
Element
(
"consumption"
)
#Then, we add two movement elements, one for cpu
tree
=
self
.
_add_movement
(
root
,
cpu_list
)
#And one for memory
tree
=
self
.
_add_movement
(
root
,
memory_list
)
#We add the XML header to the file to be valid
report
=
ElementTree
.
tostring
(
tree
)
fd
=
open
(
storage_path
,
'w'
)
fd
.
write
(
"<?xml version='1.0' encoding='utf-8'?>%s"
%
report
)
fd
.
close
()
def
_add_movement
(
self
,
consumption
,
single_resource_list
):
child_consumption
=
ElementTree
.
SubElement
(
consumption
,
"movement"
)
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"resource"
)
child_movement
.
text
=
single_resource_list
[
0
]
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"title"
)
child_movement
.
text
=
single_resource_list
[
1
]
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"reference"
)
child_movement
.
text
=
''
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"quantity"
)
child_movement
.
text
=
single_resource_list
[
2
]
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"price"
)
child_movement
.
text
=
'0.00'
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"VAT"
)
child_movement
.
text
=
''
child_movement
=
ElementTree
.
SubElement
(
child_consumption
,
"category"
)
child_movement
.
text
=
''
tree
=
self
.
element_tree
.
ElementTree
(
consumption
)
return
tree
def
parse_opt
():
usage
=
"""usage: slapmonitor [options] PID_FILE_PATH DATABASE_PATH
Usage: slapreport [options] LOG_PATH DATABASE_PATH LOGBOX_IP LOGBOX_PORT LOGBOX_LOGIN LOGBOX_PASSWORD"""
parser
=
optparse
.
OptionParser
(
usage
=
usage
)
parser
.
add_option
(
'-t'
,
'--update_time'
,
type
=
int
,
dest
=
'update_time'
,
help
=
'Specify the interval'
\
'(in seconds) to check resources consumption [default 30 seconds]'
,
default
=
3
)
parser
.
add_option
(
'-l'
,
'--log_file'
,
dest
=
'path_log_file'
,
help
=
'Specify the logfile destination path'
,
metavar
=
'FILE'
)
return
parser
class
SlapMonitor
(
object
):
def
__init__
(
self
,
proc
,
update_time
,
path_database
):
self
.
proc
=
proc
self
.
update_time
=
update_time
self
.
path_database
=
path_database
self
.
start_monitor
()
def
start_monitor
(
self
):
temporary_monitoring
=
MonitoringTool
()
#check if the process is alive == None, instead zero value == proc is over
while
self
.
proc
.
pid
in
psutil
.
get_pid_list
():
conn
=
sqlite3
.
connect
(
self
.
path_database
)
cursor
=
conn
.
cursor
()
cursor
.
execute
(
"create table if not exists data (cpu real, cpu_time real, memory real, rss real,"
\
"date text, time text, reported integer NULL DEFAULT 0)"
)
try
:
res_list
=
temporary_monitoring
.
get_cpu_and_memory_usage
(
self
.
proc
)
date_catched
=
"-"
.
join
([
str
(
res_list
[
4
].
year
),
str
(
res_list
[
4
].
month
),
str
(
res_list
[
4
].
day
)])
time_catched
=
":"
.
join
([
str
(
res_list
[
4
].
hour
),
str
(
res_list
[
4
].
minute
),
str
(
res_list
[
4
].
second
)])
res_list
[
4
]
=
date_catched
res_list
.
append
(
time_catched
)
cursor
.
execute
(
"insert into data(cpu, cpu_time, memory, rss, date, time) values (?,?,?,?,?,?)"
,
res_list
)
conn
.
commit
()
cursor
.
close
()
conn
.
close
()
time
.
sleep
(
self
.
update_time
)
except
IOError
:
if
log_file
:
logging
.
info
(
"ERROR : process with pid : %s watched by slap monitor exited too quickly at %s"
%
(
self
.
proc
.
pid
,
time
.
strftime
(
"%Y-%m-%d at %H:%m"
)))
sys
.
exit
(
1
)
if
log_file
:
logging
.
info
(
"EXIT 0: Process terminated normally!"
)
sys
.
exit
(
0
)
class
SlapReport
(
object
):
"""
reports usage of apache and mariadb logs to an existing log server
"""
def
__init__
(
self
,
proc
,
update_time
,
consumption_log_path
,
database_path
,
ssh_parameters
):
self
.
proc
=
proc
self
.
update_time
=
update_time
self
.
path_database
=
database_path
self
.
consumption_log_path
=
consumption_log_path
self
.
ssh_parameters
=
ssh_parameters
self
.
start_report
()
def
write_log
(
self
):
"""This func read data from database and through
write_log_file write result on a log file"""
#write none reported log in the consumption log log file
fd
=
open
(
self
.
consumption_log_path
,
'a'
)
conn
=
sqlite3
.
connect
(
self
.
path_database
)
cursor
=
conn
.
cursor
()
log_list
=
cursor
.
execute
(
"SELECT * FROM data WHERE reported=0 ORDER BY rowid ASC"
)
last_report_time
=
""
for
row
in
log_list
:
cpu_consumption_info
=
"%s %s Instance %s CPU Consumption: CPU:%s CPU_TIME:%s
\
n
"
\
%
(
row
[
4
],
row
[
5
],
self
.
proc
.
name
,
row
[
0
],
row
[
1
])
memory_consumption_info
=
"%s %s Instance %s Memory Consumption: %s
\
n
"
\
%
(
row
[
4
],
row
[
5
],
self
.
proc
.
name
,
row
[
2
])
try
:
cmd
=
"tail -n 2 %s | ssh %s:%s@%s -p %s "
\
%
(
self
.
consumption_log_path
,
self
.
ssh_parameters
[
'user'
],
\
self
.
ssh_parameters
[
'passwd'
],
self
.
ssh_parameters
[
'ip'
],
\
self
.
ssh_parameters
[
'port'
])
res
=
os
.
system
(
cmd
)
if
not
res
:
if
last_report_time
!=
row
[
5
]:
fd
.
write
(
"%s%s"
%
(
cpu_consumption_info
,
memory_consumption_info
))
last_report_time
=
"%s"
%
row
[
5
]
cursor
.
execute
(
"UPDATE data set reported='1' WHERE time=?"
,
(
row
[
5
],))
conn
.
commit
()
except
Exception
:
if
log_file
:
logging
.
info
(
"ERROR : Unable to connect to % at %s"
%
(
self
.
ssh_parameters
[
'ip'
],
time
.
strftime
(
"%Y-%m-%d at %H:%m"
)))
#sys.exit(1)
cursor
.
close
()
conn
.
close
()
def
start_report
(
self
):
"""
while the process is running, connect to the database
and report the non-reported line,
when line is reported put 1 to column report
"""
temporary_monitoring
=
MonitoringTool
()
#check if the process is alive == None, instead zero value == proc is over
while
self
.
proc
.
pid
in
psutil
.
get_pid_list
():
try
:
# send log to logbox
self
.
write_log
()
time
.
sleep
(
self
.
update_time
)
except
IOError
:
if
log_file
:
logging
.
info
(
"ERROR : process with pid : %s watched by slap monitor exited too quickly at %s"
%
(
self
.
proc
.
pid
,
time
.
strftime
(
"%Y-%m-%d at %H:%m"
)))
sys
.
exit
(
1
)
if
log_file
:
logging
.
info
(
"EXIT 0: Process terminated normally!"
)
sys
.
exit
(
0
)
def
run_slapmonitor
():
#This function require the pid file and the database path
parser
=
parse_opt
()
opts
,
args
=
parser
.
parse_args
()
if
len
(
args
)
!=
2
:
parser
.
error
(
"Incorrect number of arguments, 2 required but "
+
str
(
len
(
args
))
+
" detected"
)
if
opts
.
path_log_file
:
logging
.
basicConfig
(
filename
=
opts
.
path_log_file
,
level
=
logging
.
DEBUG
)
global
log_file
log_file
=
True
proc
=
psutil
.
Process
(
read_pid
(
args
[
0
]))
# XXX FIXME: THE PID IS ONLY READ ONCE.
# process death and pid reuse are not detected.
SlapMonitor
(
proc
,
opts
.
update_time
,
args
[
1
])
def
run_slapmonitor_xml
():
#This function require the database path and XML path
parser
=
parse_opt
()
opts
,
args
=
parser
.
parse_args
()
if
len
(
args
)
!=
2
:
parser
.
error
(
"Incorrect number of arguments, 2 required but "
+
str
(
len
(
args
))
+
" detected"
)
if
opts
.
path_log_file
:
logging
.
basicConfig
(
filename
=
opts
.
path_log_file
,
level
=
logging
.
DEBUG
)
global
log_file
log_file
=
True
get_xml_hand
=
GenerateXML
(
ElementTree
,
args
[
0
],
args
[
1
])
get_xml_hand
.
dump_xml
()
def
run_slapreport_
():
#This function require the xml_path and database_path
parser
=
parse_opt
()
opts
,
args
=
parser
.
parse_args
()
if
len
(
args
)
!=
2
:
parser
.
error
(
"Incorrect number of arguments, 2 required but "
+
str
(
len
(
args
))
+
" detected"
)
if
opts
.
path_log_file
:
logging
.
basicConfig
(
filename
=
opts
.
path_log_file
,
level
=
logging
.
DEBUG
)
global
log_file
log_file
=
True
get_xml_hand
=
GenerateXML
(
ElementTree
,
args
[
1
],
args
[
0
])
get_xml_hand
.
dump_xml
()
def
run_slapreport
():
#This function require the consumption_log_path and database_path ssh_parameters
parser
=
parse_opt
()
ssh_parameters
=
{}
opts
,
args
=
parser
.
parse_args
()
if
len
(
args
)
!=
7
:
parser
.
error
(
"Incorrect number of arguments, 7 required but "
+
str
(
len
(
args
))
+
" detected"
)
if
opts
.
path_log_file
:
logging
.
basicConfig
(
filename
=
opts
.
path_log_file
,
level
=
logging
.
DEBUG
)
global
log_file
log_file
=
True
if
args
[
3
]
==
""
:
sys
.
exit
(
0
)
pid_file_path
=
"%s"
%
args
[
0
]
#set ssh parameters
ssh_parameters
[
'ip'
]
=
args
[
3
]
ssh_parameters
[
'port'
]
=
args
[
4
]
ssh_parameters
[
'user'
]
=
args
[
5
]
ssh_parameters
[
'passwd'
]
=
args
[
6
]
try
:
proc
=
psutil
.
Process
(
read_pid
(
pid_file_path
))
SlapReport
(
proc
,
opts
.
update_time
,
args
[
1
],
args
[
2
],
ssh_parameters
)
except
IOError
:
if
log_file
:
logging
.
info
(
"ERROR : process with pid : %s watched by slap monitor exited too quickly at %s"
%
(
proc
.
pid
,
time
.
strftime
(
"%Y-%m-%d at %H:%m"
)))
sys
.
exit
(
1
)
if
log_file
:
logging
.
info
(
"EXIT 0: Process terminated normally!"
)
#sys.exit(0)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment