Merge branch 'new/persona' of git://github.com/harlowja/Openstack-DevstackPy into harlowja-new/persona
Conflicts: devstack/cfg_helpers.py devstack/components/db.py devstack/components/keystone.py devstack/components/nova.py
This commit is contained in:
commit
a849d7b257
@ -1,11 +1,9 @@
|
|||||||
# Ubuntu 11 (Oneiric)
|
# Ubuntu 11 (Oneiric)
|
||||||
|
|
||||||
# FIXME: Component dependencies should go into personas, not distros.
|
|
||||||
|
|
||||||
name: ubuntu-oneiric
|
name: ubuntu-oneiric
|
||||||
distro_pattern: Ubuntu(.*)oneiric
|
distro_pattern: Ubuntu(.*)oneiric
|
||||||
|
|
||||||
packager_name: devstack.packaging.apt:AptPackager
|
packager_name: devstack.distros.oneiric:OneiricAptPackager
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
|
||||||
@ -18,13 +16,15 @@ commands:
|
|||||||
status: ["service", "apache2", "status"]
|
status: ["service", "apache2", "status"]
|
||||||
settings:
|
settings:
|
||||||
conf-link-target: /etc/apache2/sites-enabled/000-default
|
conf-link-target: /etc/apache2/sites-enabled/000-default
|
||||||
|
|
||||||
|
libvirt-daemon: 'libvirt-bin'
|
||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
start: ["service", "mysql", 'start']
|
start: ["service", "mysql", 'start']
|
||||||
stop: ["service", 'mysql', "stop"]
|
stop: ["service", 'mysql', "stop"]
|
||||||
status: ["service", 'mysql', "status"]
|
status: ["service", 'mysql', "status"]
|
||||||
restart: ["service", 'mysql', "restart"]
|
restart: ["service", 'mysql', "restart"]
|
||||||
#NOTE: we aren't stopping any sql injection...
|
# NOTE: we aren't stopping any sql injection...
|
||||||
set_pwd: ['mysql', '--user=%USER%', '--password=%OLD_PASSWORD%', '-e',
|
set_pwd: ['mysql', '--user=%USER%', '--password=%OLD_PASSWORD%', '-e',
|
||||||
"\"USE mysql; UPDATE user SET password=PASSWORD('%NEW_PASSWORD%') WHERE User='%USER%'; FLUSH PRIVILEGES;\""]
|
"\"USE mysql; UPDATE user SET password=PASSWORD('%NEW_PASSWORD%') WHERE User='%USER%'; FLUSH PRIVILEGES;\""]
|
||||||
create_db: ['mysql', '--user=%USER%', '--password=%PASSWORD%', '-e', 'CREATE DATABASE %DB%;']
|
create_db: ['mysql', '--user=%USER%', '--password=%PASSWORD%', '-e', 'CREATE DATABASE %DB%;']
|
||||||
@ -32,6 +32,12 @@ commands:
|
|||||||
grant_all: ["mysql", "--user=%USER%", "--password=%PASSWORD%", '-e',
|
grant_all: ["mysql", "--user=%USER%", "--password=%PASSWORD%", '-e',
|
||||||
"\"GRANT ALL PRIVILEGES ON *.* TO '%USER%'@'%' IDENTIFIED BY '%PASSWORD%'; FLUSH PRIVILEGES;\""]
|
"\"GRANT ALL PRIVILEGES ON *.* TO '%USER%'@'%' IDENTIFIED BY '%PASSWORD%'; FLUSH PRIVILEGES;\""]
|
||||||
|
|
||||||
|
iscsi:
|
||||||
|
start: ['service', 'tgt', 'start']
|
||||||
|
stop: ['service', 'tgt', 'stop']
|
||||||
|
restart: ['service', 'tgt', 'restart']
|
||||||
|
status: ['service', 'tgt', 'status']
|
||||||
|
|
||||||
components:
|
components:
|
||||||
|
|
||||||
db:
|
db:
|
||||||
@ -151,10 +157,6 @@ components:
|
|||||||
uninstall: devstack.components.glance:GlanceUninstaller
|
uninstall: devstack.components.glance:GlanceUninstaller
|
||||||
start: devstack.components.glance:GlanceRuntime
|
start: devstack.components.glance:GlanceRuntime
|
||||||
stop: devstack.components.glance:GlanceRuntime
|
stop: devstack.components.glance:GlanceRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- keystone
|
|
||||||
- db
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-eventlet
|
- name: python-eventlet
|
||||||
version: 0.9*
|
version: 0.9*
|
||||||
@ -198,12 +200,6 @@ components:
|
|||||||
uninstall: devstack.components.horizon:HorizonUninstaller
|
uninstall: devstack.components.horizon:HorizonUninstaller
|
||||||
start: devstack.components.horizon:HorizonRuntime
|
start: devstack.components.horizon:HorizonRuntime
|
||||||
stop: devstack.components.horizon:HorizonRuntime
|
stop: devstack.components.horizon:HorizonRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- keystone-client
|
|
||||||
- glance
|
|
||||||
- nova-client
|
|
||||||
- quantum-client
|
|
||||||
packages:
|
packages:
|
||||||
- name: apache2
|
- name: apache2
|
||||||
removable: True
|
removable: True
|
||||||
@ -278,8 +274,6 @@ components:
|
|||||||
uninstall: devstack.components.keystone_client:KeyStoneClientUninstaller
|
uninstall: devstack.components.keystone_client:KeyStoneClientUninstaller
|
||||||
start: devstack.components.keystone_client:KeyStoneClientRuntime
|
start: devstack.components.keystone_client:KeyStoneClientRuntime
|
||||||
stop: devstack.components.keystone_client:KeyStoneClientRuntime
|
stop: devstack.components.keystone_client:KeyStoneClientRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-argparse
|
- name: python-argparse
|
||||||
removable: True
|
removable: True
|
||||||
@ -293,10 +287,6 @@ components:
|
|||||||
uninstall: devstack.components.keystone:KeystoneUninstaller
|
uninstall: devstack.components.keystone:KeystoneUninstaller
|
||||||
start: devstack.components.keystone:KeystoneRuntime
|
start: devstack.components.keystone:KeystoneRuntime
|
||||||
stop: devstack.components.keystone:KeystoneRuntime
|
stop: devstack.components.keystone:KeystoneRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- db
|
|
||||||
- keystone-client
|
|
||||||
packages:
|
packages:
|
||||||
- name: libldap2-dev
|
- name: libldap2-dev
|
||||||
removable: True
|
removable: True
|
||||||
@ -361,9 +351,6 @@ components:
|
|||||||
uninstall: devstack.components.melange:MelangeUninstaller
|
uninstall: devstack.components.melange:MelangeUninstaller
|
||||||
start: devstack.components.melange:MelangeRuntime
|
start: devstack.components.melange:MelangeRuntime
|
||||||
stop: devstack.components.melange:MelangeRuntime
|
stop: devstack.components.melange:MelangeRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- db
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-eventlet
|
- name: python-eventlet
|
||||||
removable: True
|
removable: True
|
||||||
@ -390,88 +377,21 @@ components:
|
|||||||
removable: True
|
removable: True
|
||||||
version: 1.0*
|
version: 1.0*
|
||||||
|
|
||||||
nova-api:
|
no-vnc:
|
||||||
# FIXME: This will report that it is installing/uninstalling
|
|
||||||
# "general" instead of the right name.
|
|
||||||
install: devstack.components.pkglist:Installer
|
|
||||||
uninstall: devstack.components.pkglist:Uninstaller
|
|
||||||
start: devstack.component:EmptyRuntime
|
|
||||||
stop: devstack.component:EmptyRuntime
|
|
||||||
packages:
|
|
||||||
- name: python-dateutil
|
|
||||||
removable: True
|
|
||||||
version: 1.4*
|
|
||||||
|
|
||||||
nova-cpu:
|
|
||||||
# FIXME: This will report that it is installing/uninstalling
|
|
||||||
# "general" instead of the right name.
|
|
||||||
install: devstack.components.pkglist:Installer
|
|
||||||
uninstall: devstack.components.pkglist:Uninstaller
|
|
||||||
start: devstack.component:EmptyRuntime
|
|
||||||
stop: devstack.component:EmptyRuntime
|
|
||||||
packages:
|
|
||||||
- name: kvm
|
|
||||||
removable: True
|
|
||||||
version: 1:84*
|
|
||||||
- name: libvirt-bin
|
|
||||||
removable: True
|
|
||||||
version: 0.9*
|
|
||||||
- name: libvirt0
|
|
||||||
removable: True
|
|
||||||
version: 0.9*
|
|
||||||
- name: lvm2
|
|
||||||
removable: True
|
|
||||||
version: 2.02*
|
|
||||||
- name: open-iscsi
|
|
||||||
removable: True
|
|
||||||
version: 2.0*
|
|
||||||
- name: open-iscsi-utils
|
|
||||||
removable: True
|
|
||||||
version: 2.0*
|
|
||||||
- name: python-libvirt
|
|
||||||
removable: True
|
|
||||||
version: 0.9.2*
|
|
||||||
- name: qemu-kvm
|
|
||||||
removable: True
|
|
||||||
version: 0.14.*
|
|
||||||
|
|
||||||
n-vnc:
|
|
||||||
install: devstack.components.novnc:NoVNCInstaller
|
install: devstack.components.novnc:NoVNCInstaller
|
||||||
uninstall: devstack.components.novnc:NoVNCUninstaller
|
uninstall: devstack.components.novnc:NoVNCUninstaller
|
||||||
start: devstack.components.novnc:NoVNCRuntime
|
start: devstack.components.novnc:NoVNCRuntime
|
||||||
stop: devstack.components.novnc:NoVNCRuntime
|
stop: devstack.components.novnc:NoVNCRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-numpy
|
- name: python-numpy
|
||||||
removable: True
|
removable: True
|
||||||
version: 1:1.5*
|
version: 1:1.5*
|
||||||
|
|
||||||
nova-vol:
|
|
||||||
# FIXME: This will report that it is installing/uninstalling
|
|
||||||
# "general" instead of the right name.
|
|
||||||
install: devstack.components.pkglist:Installer
|
|
||||||
uninstall: devstack.components.pkglist:Uninstaller
|
|
||||||
start: devstack.component:EmptyRuntime
|
|
||||||
stop: devstack.component:EmptyRuntime
|
|
||||||
packages:
|
|
||||||
- name: iscsitarget
|
|
||||||
removable: True
|
|
||||||
version: 1.4*
|
|
||||||
- name: lvm2
|
|
||||||
removable: True
|
|
||||||
version: 2.02*
|
|
||||||
- name: tgt
|
|
||||||
removable: True
|
|
||||||
version: 1:1*
|
|
||||||
|
|
||||||
nova-client:
|
nova-client:
|
||||||
install: devstack.components.nova_client:NovaClientInstaller
|
install: devstack.components.nova_client:NovaClientInstaller
|
||||||
uninstall: devstack.components.nova_client:NovaClientUninstaller
|
uninstall: devstack.components.nova_client:NovaClientUninstaller
|
||||||
start: devstack.components.nova_client:NovaClientRuntime
|
start: devstack.components.nova_client:NovaClientRuntime
|
||||||
stop: devstack.components.nova_client:NovaClientRuntime
|
stop: devstack.components.nova_client:NovaClientRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-argparse
|
- name: python-argparse
|
||||||
removable: True
|
removable: True
|
||||||
@ -485,16 +405,6 @@ components:
|
|||||||
uninstall: devstack.components.nova:NovaUninstaller
|
uninstall: devstack.components.nova:NovaUninstaller
|
||||||
start: devstack.components.nova:NovaRuntime
|
start: devstack.components.nova:NovaRuntime
|
||||||
stop: devstack.components.nova:NovaRuntime
|
stop: devstack.components.nova:NovaRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- keystone
|
|
||||||
- glance
|
|
||||||
- db
|
|
||||||
- rabbit
|
|
||||||
- nova-client
|
|
||||||
- nova-cpu
|
|
||||||
- nova-vol
|
|
||||||
- nova-api
|
|
||||||
packages:
|
packages:
|
||||||
- name: dnsmasq-base
|
- name: dnsmasq-base
|
||||||
removable: True
|
removable: True
|
||||||
@ -596,51 +506,65 @@ components:
|
|||||||
pips:
|
pips:
|
||||||
- name: iso8601
|
- name: iso8601
|
||||||
version: 0.1.4
|
version: 0.1.4
|
||||||
|
subsystems:
|
||||||
|
vol:
|
||||||
|
packages:
|
||||||
|
- name: iscsitarget
|
||||||
|
removable: True
|
||||||
|
version: 1.4*
|
||||||
|
- name: lvm2
|
||||||
|
removable: True
|
||||||
|
version: 2.02*
|
||||||
|
- name: tgt
|
||||||
|
removable: True
|
||||||
|
version: 1:1*
|
||||||
|
api:
|
||||||
|
packages:
|
||||||
|
- name: python-dateutil
|
||||||
|
removable: True
|
||||||
|
version: 1.4*
|
||||||
|
cpu:
|
||||||
|
packages:
|
||||||
|
- name: kvm
|
||||||
|
removable: True
|
||||||
|
version: 1:84*
|
||||||
|
- name: libvirt-bin
|
||||||
|
removable: True
|
||||||
|
version: 0.9*
|
||||||
|
- name: libvirt0
|
||||||
|
removable: True
|
||||||
|
version: 0.9*
|
||||||
|
- name: lvm2
|
||||||
|
removable: True
|
||||||
|
version: 2.02*
|
||||||
|
- name: open-iscsi
|
||||||
|
removable: True
|
||||||
|
version: 2.0*
|
||||||
|
- name: open-iscsi-utils
|
||||||
|
removable: True
|
||||||
|
version: 2.0*
|
||||||
|
- name: python-libvirt
|
||||||
|
removable: True
|
||||||
|
version: 0.9.2*
|
||||||
|
- name: qemu-kvm
|
||||||
|
removable: True
|
||||||
|
version: 0.14.*
|
||||||
|
|
||||||
quantum-client:
|
quantum-client:
|
||||||
install: devstack.components.quantum_client:QuantumClientInstaller
|
install: devstack.components.quantum_client:QuantumClientInstaller
|
||||||
uninstall: devstack.components.quantum_client:QuantumClientUninstaller
|
uninstall: devstack.components.quantum_client:QuantumClientUninstaller
|
||||||
start: devstack.components.quantum_client:QuantumClientRuntime
|
start: devstack.components.quantum_client:QuantumClientRuntime
|
||||||
stop: devstack.components.quantum_client:QuantumClientRuntime
|
stop: devstack.components.quantum_client:QuantumClientRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-gflags
|
- name: python-gflags
|
||||||
removable: True
|
removable: True
|
||||||
version: 1.5*
|
version: 1.5*
|
||||||
|
|
||||||
quantum-openvswitch:
|
|
||||||
# FIXME: This will report that it is installing/uninstalling
|
|
||||||
# "general" instead of the right name.
|
|
||||||
install: devstack.components.pkglist:Installer
|
|
||||||
uninstall: devstack.components.pkglist:Uninstaller
|
|
||||||
start: devstack.component:EmptyRuntime
|
|
||||||
stop: devstack.component:EmptyRuntime
|
|
||||||
packages:
|
|
||||||
- name: openvswitch-datapath-dkms
|
|
||||||
removable: True
|
|
||||||
version: 1.2*
|
|
||||||
- name: openvswitch-switch
|
|
||||||
removable: True
|
|
||||||
version: 1.2*
|
|
||||||
- name: python-mysqldb
|
|
||||||
removable: True
|
|
||||||
version: 1.2*
|
|
||||||
- name: python-sqlalchemy
|
|
||||||
removable: True
|
|
||||||
version: 0.6*
|
|
||||||
|
|
||||||
quantum:
|
quantum:
|
||||||
install: devstack.components.quantum:QuantumInstaller
|
install: devstack.components.quantum:QuantumInstaller
|
||||||
uninstall: devstack.components.quantum:QuantumUninstaller
|
uninstall: devstack.components.quantum:QuantumUninstaller
|
||||||
start: devstack.components.quantum:QuantumRuntime
|
start: devstack.components.quantum:QuantumRuntime
|
||||||
stop: devstack.components.quantum:QuantumRuntime
|
stop: devstack.components.quantum:QuantumRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- quantum-client
|
|
||||||
# Default is to include openvswitch so it is here until
|
|
||||||
# we add proper persona support.
|
|
||||||
- quantum-openvswitch
|
|
||||||
packages:
|
packages:
|
||||||
- name: python-eventlet
|
- name: python-eventlet
|
||||||
removable: True
|
removable: True
|
||||||
@ -663,8 +587,23 @@ components:
|
|||||||
- name: python-routes
|
- name: python-routes
|
||||||
removable: True
|
removable: True
|
||||||
version: 1.12*
|
version: 1.12*
|
||||||
|
subsystems:
|
||||||
|
openvswitch:
|
||||||
|
packages:
|
||||||
|
- name: openvswitch-datapath-dkms
|
||||||
|
removable: True
|
||||||
|
version: 1.2*
|
||||||
|
- name: openvswitch-switch
|
||||||
|
removable: True
|
||||||
|
version: 1.2*
|
||||||
|
- name: python-mysqldb
|
||||||
|
removable: True
|
||||||
|
version: 1.2*
|
||||||
|
- name: python-sqlalchemy
|
||||||
|
removable: True
|
||||||
|
version: 0.6*
|
||||||
|
|
||||||
rabbit:
|
rabbit-mq:
|
||||||
install: devstack.components.rabbit:RabbitInstaller
|
install: devstack.components.rabbit:RabbitInstaller
|
||||||
uninstall: devstack.components.rabbit:RabbitUninstaller
|
uninstall: devstack.components.rabbit:RabbitUninstaller
|
||||||
start: devstack.components.rabbit:RabbitRuntime
|
start: devstack.components.rabbit:RabbitRuntime
|
||||||
@ -679,9 +618,6 @@ components:
|
|||||||
uninstall: devstack.components.swift:SwiftUninstaller
|
uninstall: devstack.components.swift:SwiftUninstaller
|
||||||
start: devstack.components.swift:SwiftRuntime
|
start: devstack.components.swift:SwiftRuntime
|
||||||
stop: devstack.components.swift:SwiftRuntime
|
stop: devstack.components.swift:SwiftRuntime
|
||||||
dependencies:
|
|
||||||
- general
|
|
||||||
- keystone-client
|
|
||||||
packages:
|
packages:
|
||||||
- name: memcached
|
- name: memcached
|
||||||
removable: True
|
removable: True
|
||||||
|
31
conf/personas/devstack.sh.yaml
Normal file
31
conf/personas/devstack.sh.yaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
created_on: Wed, 14 Mar 2012 17:28:24 -0700
|
||||||
|
description: Devstack.sh matching component installation (as of the above date).
|
||||||
|
supports:
|
||||||
|
- rhel-6
|
||||||
|
- ubuntu-oneiric
|
||||||
|
- fedora-16
|
||||||
|
components:
|
||||||
|
- db
|
||||||
|
- rabbit-mq
|
||||||
|
- keystone-client
|
||||||
|
- keystone
|
||||||
|
- glance
|
||||||
|
- nova
|
||||||
|
- no-vnc
|
||||||
|
- quantum-client
|
||||||
|
- nova-client
|
||||||
|
- horizon
|
||||||
|
subsystems:
|
||||||
|
glance:
|
||||||
|
- api
|
||||||
|
- reg
|
||||||
|
nova:
|
||||||
|
- api
|
||||||
|
- cauth
|
||||||
|
- cert
|
||||||
|
- cpu
|
||||||
|
- net
|
||||||
|
- sched
|
||||||
|
- vol
|
||||||
|
- xvnc
|
@ -1,15 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"coverage": {
|
|
||||||
"version": "3.5.1"
|
|
||||||
},
|
|
||||||
"nose": {
|
|
||||||
"version": "1.1.2"
|
|
||||||
},
|
|
||||||
"mock": {
|
|
||||||
"version": "0.8.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"SQLAlchemy": {
|
|
||||||
"version": "0.7.5"
|
|
||||||
},
|
|
||||||
"Routes": {
|
|
||||||
"version": "1.12.3"
|
|
||||||
},
|
|
||||||
#the base is 2.0, need to upgrade
|
|
||||||
"pycrypto": {
|
|
||||||
"version": "2.5",
|
|
||||||
"options": "--upgrade"
|
|
||||||
},
|
|
||||||
#the newest we can get is 1.3.3 from epel/rhel
|
|
||||||
#this causes issues like the following
|
|
||||||
#https://answers.launchpad.net/nova/+question/174160
|
|
||||||
"PasteDeploy": {
|
|
||||||
"version": "1.5.0"
|
|
||||||
},
|
|
||||||
"iso8601": {
|
|
||||||
"version": "0.1.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
#the base is 2.0, need to upgrade
|
|
||||||
"pycrypto": {
|
|
||||||
"version": "2.5",
|
|
||||||
"options": "--upgrade"
|
|
||||||
},
|
|
||||||
#the newest we can get is 1.3.3 from epel/rhel
|
|
||||||
#this causes issues like the following
|
|
||||||
#https://answers.launchpad.net/nova/+question/174160
|
|
||||||
#https://answers.launchpad.net/nova/+question/185116
|
|
||||||
"PasteDeploy": {
|
|
||||||
"version": "1.5"
|
|
||||||
},
|
|
||||||
"PasteScript": {
|
|
||||||
"version": "1.7.5"
|
|
||||||
},
|
|
||||||
"Paste": {
|
|
||||||
"version": "1.7.5.1"
|
|
||||||
},
|
|
||||||
"SQLAlchemy": {
|
|
||||||
"version": "0.7.5"
|
|
||||||
},
|
|
||||||
"sqlalchemy-migrate": {
|
|
||||||
"version": "0.7.2"
|
|
||||||
},
|
|
||||||
"python-cloudfiles": {
|
|
||||||
"version": "1.7.9.3"
|
|
||||||
},
|
|
||||||
"CherryPy": {
|
|
||||||
"version": "3.2.2"
|
|
||||||
},
|
|
||||||
#the base os doesn't have static files which
|
|
||||||
#seems only in 1.3 or greater
|
|
||||||
"django" : {
|
|
||||||
"version": "1.3.1"
|
|
||||||
},
|
|
||||||
"django-nose" : {
|
|
||||||
"version": "0.1.3"
|
|
||||||
},
|
|
||||||
"django-nose-selenium": {
|
|
||||||
"version": "0.7.3"
|
|
||||||
},
|
|
||||||
"django-registration" : {
|
|
||||||
"version": "0.7"
|
|
||||||
},
|
|
||||||
"django-mailer" : {
|
|
||||||
"version": "0.1.0"
|
|
||||||
},
|
|
||||||
"django-staticfiles" : {
|
|
||||||
"version": "1.1.2"
|
|
||||||
},
|
|
||||||
"Routes": {
|
|
||||||
"version": "1.12.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
# rpm 1.7.9.1 does not have exceptions.Error
|
|
||||||
"python-cloudfiles": {
|
|
||||||
"version": "1.7.9.3"
|
|
||||||
},
|
|
||||||
"django-nose" : {
|
|
||||||
"version": "0.1.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"SQLAlchemy": {
|
|
||||||
"version": "0.7.5"
|
|
||||||
},
|
|
||||||
"sqlalchemy-migrate": {
|
|
||||||
"version": "0.7.2"
|
|
||||||
},
|
|
||||||
#the base is 2.0, need to upgrade
|
|
||||||
"pycrypto": {
|
|
||||||
"version": "2.5",
|
|
||||||
"options": "--upgrade"
|
|
||||||
},
|
|
||||||
"py-bcrypt": {
|
|
||||||
"version": "0.2"
|
|
||||||
},
|
|
||||||
"Routes": {
|
|
||||||
"version": "1.12.3"
|
|
||||||
},
|
|
||||||
#the newest we can get is 1.3.3 from epel/rhel
|
|
||||||
#this causes issues like the following
|
|
||||||
#https://answers.launchpad.net/nova/+question/174160
|
|
||||||
#https://answers.launchpad.net/nova/+question/185116
|
|
||||||
"PasteDeploy": {
|
|
||||||
"version": "1.5"
|
|
||||||
},
|
|
||||||
"PasteScript": {
|
|
||||||
"version": "1.7.5"
|
|
||||||
},
|
|
||||||
"Paste": {
|
|
||||||
"version": "1.7.5.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"numpy": {
|
|
||||||
"version": "1.5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"SQLAlchemy": {
|
|
||||||
"version": "0.7.5"
|
|
||||||
},
|
|
||||||
#the base is 0.4, need to upgrade (?)
|
|
||||||
"Tempita": {
|
|
||||||
"version": "0.5dev",
|
|
||||||
"options": "--upgrade"
|
|
||||||
},
|
|
||||||
"sqlalchemy-migrate": {
|
|
||||||
"version": "0.7.2"
|
|
||||||
},
|
|
||||||
#the base is 2.0, need to upgrade
|
|
||||||
"pycrypto": {
|
|
||||||
"version": "2.5",
|
|
||||||
"options": "--upgrade"
|
|
||||||
},
|
|
||||||
"Routes": {
|
|
||||||
"version": "1.12.3"
|
|
||||||
},
|
|
||||||
#the newest we can get is 1.3.3 from epel/rhel
|
|
||||||
#this causes issues like the following
|
|
||||||
#https://answers.launchpad.net/nova/+question/174160
|
|
||||||
#https://answers.launchpad.net/nova/+question/185116
|
|
||||||
"PasteDeploy": {
|
|
||||||
"version": "1.5"
|
|
||||||
},
|
|
||||||
"PasteScript": {
|
|
||||||
"version": "1.7.5"
|
|
||||||
},
|
|
||||||
"Paste": {
|
|
||||||
"version": "1.7.5.1"
|
|
||||||
},
|
|
||||||
"iso8601": {
|
|
||||||
"version": "0.1.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
"rhel-6": {
|
|
||||||
"SQLAlchemy": {
|
|
||||||
"version": "0.7.5"
|
|
||||||
},
|
|
||||||
"sqlalchemy-migrate": {
|
|
||||||
"version": "0.7.2"
|
|
||||||
},
|
|
||||||
#the newest we can get is 1.3.3 from epel/rhel
|
|
||||||
#this causes issues like the following
|
|
||||||
#https://answers.launchpad.net/nova/+question/174160
|
|
||||||
#https://answers.launchpad.net/nova/+question/185116
|
|
||||||
"PasteDeploy": {
|
|
||||||
"version": "1.5"
|
|
||||||
},
|
|
||||||
"PasteScript": {
|
|
||||||
"version": "1.7.5"
|
|
||||||
},
|
|
||||||
"Paste": {
|
|
||||||
"version": "1.7.5.1"
|
|
||||||
},
|
|
||||||
"Routes": {
|
|
||||||
"version": "1.12.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"ubuntu-oneiric": {
|
|
||||||
"mysql-client-5.1": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mysql-server-core-5.1": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mysql-common": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mysql-server-5.1": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true,
|
|
||||||
"pre-install": [
|
|
||||||
{
|
|
||||||
# This apparently is a action needed for ubuntu/debian to set the password to something known....
|
|
||||||
"run_as_root": true,
|
|
||||||
"cmd": [
|
|
||||||
"debconf-set-selections"
|
|
||||||
],
|
|
||||||
"stdin": [
|
|
||||||
"mysql-server-5.1 mysql-server/root_password password %PASSWORD%",
|
|
||||||
"mysql-server-5.1 mysql-server/root_password_again password %PASSWORD%",
|
|
||||||
"mysql-server-5.1 mysql-server/start_on_boot boolean %BOOT_START%"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rhel-6": {
|
|
||||||
"mysql-server": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mysql": {
|
|
||||||
"version": "5.1*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"mysql-server": {
|
|
||||||
"version": "5.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mysql": {
|
|
||||||
"version": "5.5*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,255 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"curl": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "7.19.7*"
|
|
||||||
},
|
|
||||||
"euca2ools": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.3.1*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"git": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.7*"
|
|
||||||
},
|
|
||||||
"gawk": {
|
|
||||||
"version": "3.1*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"iputils": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "20071127*"
|
|
||||||
},
|
|
||||||
"mlocate": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.22*"
|
|
||||||
},
|
|
||||||
"lsof": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.82*"
|
|
||||||
},
|
|
||||||
"openssh-server": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "5.3*"
|
|
||||||
},
|
|
||||||
"python-pep8": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.6*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"psmisc": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "22.6*"
|
|
||||||
},
|
|
||||||
"pylint": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.21*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.6*"
|
|
||||||
},
|
|
||||||
"python-pip": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.8*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-unittest2": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.5.1*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-virtualenv": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.7*",
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-setuptools": {
|
|
||||||
"version": "0.6.10*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-distutils-extra": {
|
|
||||||
"version": "2.29*",
|
|
||||||
"removable": false,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-devel": {
|
|
||||||
"version": "2.6*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-mox": {
|
|
||||||
"version": "0.5.3*",
|
|
||||||
"removable": false,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"screen": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.0.3*"
|
|
||||||
},
|
|
||||||
"sudo": {
|
|
||||||
"removable": false,
|
|
||||||
"version" : "1.7.4*"
|
|
||||||
},
|
|
||||||
"tcpdump": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.0*"
|
|
||||||
},
|
|
||||||
"unzip": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "6.0*"
|
|
||||||
},
|
|
||||||
"wget": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.12*"
|
|
||||||
},
|
|
||||||
"libxml2-devel": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.7*"
|
|
||||||
},
|
|
||||||
"libxslt-devel": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.1.26*"
|
|
||||||
},
|
|
||||||
"coreutils": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "8.4*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"curl": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "7.21.7*"
|
|
||||||
},
|
|
||||||
"euca2ools": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.3.1*"
|
|
||||||
},
|
|
||||||
"git": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.7*"
|
|
||||||
},
|
|
||||||
"gawk": {
|
|
||||||
"version": "4.0*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"iputils": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "20101006*"
|
|
||||||
},
|
|
||||||
"mlocate": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.24*"
|
|
||||||
},
|
|
||||||
"lsof": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.84*"
|
|
||||||
},
|
|
||||||
"openssh-server": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "5.8*"
|
|
||||||
},
|
|
||||||
"python-pep8": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.6*"
|
|
||||||
},
|
|
||||||
"psmisc": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "22.13*"
|
|
||||||
},
|
|
||||||
"pylint": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.24*"
|
|
||||||
},
|
|
||||||
"python": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.7*"
|
|
||||||
},
|
|
||||||
"python-coverage": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "3.5*"
|
|
||||||
},
|
|
||||||
"python-pip": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.8*"
|
|
||||||
},
|
|
||||||
"python-unittest2": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "0.5.1*"
|
|
||||||
},
|
|
||||||
"python-virtualenv": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.7*"
|
|
||||||
},
|
|
||||||
"python-setuptools": {
|
|
||||||
"version": "0.6.24*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-distutils-extra": {
|
|
||||||
"version": "2.29*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-devel": {
|
|
||||||
"version": "2.7*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-nose": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-mox": {
|
|
||||||
"version": "0.5.3*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"screen": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.1.0*"
|
|
||||||
},
|
|
||||||
"sudo": {
|
|
||||||
"removable": false,
|
|
||||||
"version" : "1.8.3*"
|
|
||||||
},
|
|
||||||
"tcpdump": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "4.1*"
|
|
||||||
},
|
|
||||||
"unzip": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "6.0*"
|
|
||||||
},
|
|
||||||
"wget": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.12*"
|
|
||||||
},
|
|
||||||
"libxml2-devel": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.7*"
|
|
||||||
},
|
|
||||||
"libxslt-devel": {
|
|
||||||
"removable": false,
|
|
||||||
"version": "1.1.26*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-httplib2": {
|
|
||||||
"version": "0.4*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-routes": {
|
|
||||||
"version": "1.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-httplib2": {
|
|
||||||
"version": "0.6*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,124 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"httpd": {
|
|
||||||
"version": "2.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mod_wsgi": {
|
|
||||||
"version": "3.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-webob1.0": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-kombu": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
# initially stolen from ubuntu-oneric
|
|
||||||
"fedora-16": {
|
|
||||||
"httpd": {
|
|
||||||
"version": "2.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"mod_wsgi": {
|
|
||||||
"version": "3.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste": {
|
|
||||||
"version": "1.7.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste-deploy": {
|
|
||||||
"version": "1.5.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-routes": {
|
|
||||||
"version": "1.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-sqlalchemy": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-webob": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-kombu": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-sphinx": {
|
|
||||||
"version": "1.0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-cherrypy": {
|
|
||||||
"version": "3.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"Django": {
|
|
||||||
"version": "1.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# Not packaged yet
|
|
||||||
# "python-django-mailer": {
|
|
||||||
# "version": "0.2*",
|
|
||||||
# "removable": true
|
|
||||||
# },
|
|
||||||
# Is this really needed?
|
|
||||||
# Only in F16 testing repo
|
|
||||||
# "python-django-nose": {
|
|
||||||
# "version": "0.1*",
|
|
||||||
# "removable": true
|
|
||||||
# },
|
|
||||||
"django-registration": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-cloudfiles": {
|
|
||||||
"version": "1.7.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-migrate": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,165 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-lxml": {
|
|
||||||
# Trashes IPA client, which is probably bad
|
|
||||||
"version": "2.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"sqlite": {
|
|
||||||
"version": "3.6*",
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-sqlite2": {
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-webob1.0": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-passlib": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"openldap": {
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.4*"
|
|
||||||
},
|
|
||||||
"openldap-devel": {
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": true,
|
|
||||||
"version": "2.4*"
|
|
||||||
},
|
|
||||||
"cyrus-sasl-lib": {
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"version": "2.1*",
|
|
||||||
"removable": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-lxml": {
|
|
||||||
# Trashes IPA client, which is probably bad
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste-script": {
|
|
||||||
"version": "1.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-migrate": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste-deploy": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste": {
|
|
||||||
"version": "1.7.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"sqlite": {
|
|
||||||
"version": "3.7*",
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-sqlite2": {
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-sqlalchemy": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-webob": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-routes": {
|
|
||||||
"version": "1.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-passlib": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"openldap": {
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false,
|
|
||||||
"version": "2.4*"
|
|
||||||
},
|
|
||||||
"cyrus-sasl-lib": {
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"version": "2.1*",
|
|
||||||
"removable": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
# TBD
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-dateutil": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"lvm2": {
|
|
||||||
"version": "2.02*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iscsi-initiator-utils": {
|
|
||||||
"version": "6.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# Only really needed if you plan on using kvm
|
|
||||||
"qemu-kvm": {
|
|
||||||
"version": "2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"qemu-img": {
|
|
||||||
"version": "0.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt-python": {
|
|
||||||
"version": "0.9.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt-client": {
|
|
||||||
"version": "0.9.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt": {
|
|
||||||
"version": "0.9.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libguestfs": {
|
|
||||||
"version": "1.2.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libguestfs-mount": {
|
|
||||||
"version": "1.7.17*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libguestfs-tools": {
|
|
||||||
"version": "1.7.17*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"lvm2": {
|
|
||||||
"version": "2.02*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iscsi-initiator-utils": {
|
|
||||||
"version": "6.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"qemu-system-x86": {
|
|
||||||
"version": "0.15*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"qemu-img": {
|
|
||||||
"version": "0.15*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt-python": {
|
|
||||||
"version": "0.9.6*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt-client": {
|
|
||||||
"version": "0.9.6*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"libvirt": {
|
|
||||||
"version": "0.9.6*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"numpy": {
|
|
||||||
"version": "1.6*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"lvm2": {
|
|
||||||
"version": "2.02*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"scsi-target-utils": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iscsi-initiator-utils": {
|
|
||||||
"version": "6.2*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"lvm2": {
|
|
||||||
"version": "2.02*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"scsi-target-utils": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iscsi-initiator-utils": {
|
|
||||||
"version": "6.2*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-argparse": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-prettytable": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,264 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
# For dhcp_release
|
|
||||||
"dnsmasq": {
|
|
||||||
"version": "2.48*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"kpartx": {
|
|
||||||
"version": "0.4*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"parted": {
|
|
||||||
"version": "2.1*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"iputils": {
|
|
||||||
"version": "20071127*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# Needed for glance which is needed for nova --- this shouldn't be here
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
# Needed for glance which is needed for nova --- this shouldn't be here
|
|
||||||
"python-lxml": {
|
|
||||||
"version": "2.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iptables": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"ebtables": {
|
|
||||||
"version": "2.0*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"sqlite": {
|
|
||||||
"version": "3.6*",
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
# ???
|
|
||||||
# "vlan": {
|
|
||||||
# "version": "1.9*",
|
|
||||||
# "removable": true
|
|
||||||
# },
|
|
||||||
# Used by ajaxterm
|
|
||||||
"socat": {
|
|
||||||
"version": "1.7*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
# This seems to kill RHN/yum if its removed ??
|
|
||||||
"libxml2-python": {
|
|
||||||
"version": "2.7*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-netaddr": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-cheetah": {
|
|
||||||
"version": "2.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-carrot": {
|
|
||||||
"version": "0.10*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-suds": {
|
|
||||||
"version": "0.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-lockfile": {
|
|
||||||
"version": "0.8*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-crypto": {
|
|
||||||
"version": "2.0*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-boto": {
|
|
||||||
"version": "2.0*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-kombu": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-feedparser": {
|
|
||||||
"version": "5.0*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
# For dhcp_release
|
|
||||||
"dnsmasq": {
|
|
||||||
"version": "2.58*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"kpartx": {
|
|
||||||
"version": "0.4*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"parted": {
|
|
||||||
"version": "3.0*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"iputils": {
|
|
||||||
"version": "20101006*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# Needed for glance which is needed for nova --- this shouldn't be here
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# Needed for glance which is needed for nova --- this shouldn't be here
|
|
||||||
"python-lxml": {
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"iptables": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"ebtables": {
|
|
||||||
"version": "2.0*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"sqlite": {
|
|
||||||
"version": "3.7*",
|
|
||||||
# Trashes alot of the base os (so we don't allow it to be removed)
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
# ???
|
|
||||||
# "vconfig": {
|
|
||||||
# "version": "1.9*",
|
|
||||||
# "removable": true
|
|
||||||
# },
|
|
||||||
# Used by ajaxterm
|
|
||||||
"socat": {
|
|
||||||
"version": "1.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste": {
|
|
||||||
"version": "1.7.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
# This seems to kill RHN/yum if its removed ??
|
|
||||||
# TODO verify...libxml2-python dependencies do not include yum
|
|
||||||
"libxml2-python": {
|
|
||||||
"version": "2.7*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-routes": {
|
|
||||||
"version": "1.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-netaddr": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-cheetah": {
|
|
||||||
"version": "2.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-carrot": {
|
|
||||||
"version": "0.10*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-suds": {
|
|
||||||
"version": "0.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-lockfile": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-crypto": {
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": false
|
|
||||||
},
|
|
||||||
"python-boto": {
|
|
||||||
"version": "2.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-kombu": {
|
|
||||||
"version": "1.1*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-feedparser": {
|
|
||||||
"version": "5.0*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
# Seems needed for ovs_quantum_agent.py
|
|
||||||
"python-sqlalchemy": {
|
|
||||||
"version": "0.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"MySQL-python": {
|
|
||||||
"version": "1.2*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3.1*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"libxml2-python": {
|
|
||||||
"version": "2.7*",
|
|
||||||
"removable": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-routes": {
|
|
||||||
"version": "1.12*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-lxml": {
|
|
||||||
"version": "2.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste": {
|
|
||||||
"version": "1.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-gflags": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste-deploy": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
"rabbitmq-server": {
|
|
||||||
"version": "2.6*",
|
|
||||||
"removable": true,
|
|
||||||
"meta": {
|
|
||||||
"epel" : true
|
|
||||||
},
|
|
||||||
"pre-install": [
|
|
||||||
{
|
|
||||||
# Qpidd runs on the same port
|
|
||||||
"run_as_root": true,
|
|
||||||
"ignore_failure": true,
|
|
||||||
"cmd": [
|
|
||||||
"service",
|
|
||||||
"qpidd",
|
|
||||||
"stop"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
# Qpidd runs on the same port
|
|
||||||
"run_as_root": true,
|
|
||||||
"ignore_failure": true,
|
|
||||||
"cmd": [
|
|
||||||
"chkconfig",
|
|
||||||
"qpidd",
|
|
||||||
"off"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
"rabbitmq-server": {
|
|
||||||
"version": "2.6*",
|
|
||||||
"removable": true,
|
|
||||||
"pre-install": [
|
|
||||||
{
|
|
||||||
# Qpidd runs on the same port
|
|
||||||
"run_as_root": true,
|
|
||||||
"cmd": [
|
|
||||||
"service",
|
|
||||||
"qpidd",
|
|
||||||
"stop"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
# Qpidd runs on the same port
|
|
||||||
"run_as_root": true,
|
|
||||||
"ignore_failure": true,
|
|
||||||
"cmd": [
|
|
||||||
"chkconfig",
|
|
||||||
"qpidd",
|
|
||||||
"off"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
# This is a extended json package definition file
|
|
||||||
# We allow simple comments (lines starting with a hash symbol)
|
|
||||||
{
|
|
||||||
# This is currently our "master" repo set with versions
|
|
||||||
# that we are trying to align other distributions with.
|
|
||||||
# The versions should at least be major + minor!
|
|
||||||
"rhel-6": {
|
|
||||||
# TBD
|
|
||||||
},
|
|
||||||
"fedora-16": {
|
|
||||||
# installed for swift-keystone
|
|
||||||
"memcached": {
|
|
||||||
"version": "1.4*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-configobj": {
|
|
||||||
"version": "4.7*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-eventlet": {
|
|
||||||
"version": "0.9*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-greenlet": {
|
|
||||||
"version": "0.3*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-netifaces": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-paste-deploy": {
|
|
||||||
"version": "1.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"python-webob": {
|
|
||||||
"version": "1.0*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"pyxattr": {
|
|
||||||
"version": "0.5*",
|
|
||||||
"removable": true
|
|
||||||
},
|
|
||||||
"sqlite": {
|
|
||||||
"version": "3.7*",
|
|
||||||
"removable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,7 @@ from devstack import date
|
|||||||
from devstack import env
|
from devstack import env
|
||||||
from devstack import exceptions as excp
|
from devstack import exceptions as excp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
|
from devstack import settings
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
@ -31,6 +32,16 @@ SUB_MATCH = re.compile(r"(?:\$\(([\w\d]+):([\w\d]+))\)")
|
|||||||
CACHE_MSG = "(value will now be internally cached)"
|
CACHE_MSG = "(value will now be internally cached)"
|
||||||
|
|
||||||
|
|
||||||
|
def get_config(cfg_fn=None, cfg_cls=None):
|
||||||
|
if not cfg_fn:
|
||||||
|
cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION)
|
||||||
|
if not cfg_cls:
|
||||||
|
cfg_cls = StackConfigParser
|
||||||
|
config_instance = cfg_cls()
|
||||||
|
config_instance.read(cfg_fn)
|
||||||
|
return config_instance
|
||||||
|
|
||||||
|
|
||||||
class IgnoreMissingConfigParser(ConfigParser.RawConfigParser):
|
class IgnoreMissingConfigParser(ConfigParser.RawConfigParser):
|
||||||
DEF_INT = 0
|
DEF_INT = 0
|
||||||
DEF_FLOAT = 0.0
|
DEF_FLOAT = 0.0
|
||||||
|
@ -30,7 +30,5 @@ def make_id(section, option):
|
|||||||
|
|
||||||
|
|
||||||
def fetch_run_type(config):
|
def fetch_run_type(config):
|
||||||
run_type = config.getdefaulted("default", "run_type",
|
run_type = config.getdefaulted("default", "run_type", settings.RUN_TYPE_DEF)
|
||||||
settings.RUN_TYPE_DEF)
|
return run_type.upper()
|
||||||
run_type = run_type.upper()
|
|
||||||
return run_type
|
|
||||||
|
@ -32,93 +32,106 @@ from devstack.runners import screen
|
|||||||
|
|
||||||
LOG = logging.getLogger("devstack.component")
|
LOG = logging.getLogger("devstack.component")
|
||||||
|
|
||||||
#how we actually setup and unsetup python
|
# How we actually setup and unsetup python
|
||||||
PY_INSTALL = ['python', 'setup.py', 'develop']
|
PY_INSTALL = ['python', 'setup.py', 'develop']
|
||||||
PY_UNINSTALL = ['python', 'setup.py', 'develop', '--uninstall']
|
PY_UNINSTALL = ['python', 'setup.py', 'develop', '--uninstall']
|
||||||
|
|
||||||
#runtime status constants (return by runtime status)
|
# Runtime status constants (return by runtime status)
|
||||||
|
# TODO: move...
|
||||||
STATUS_UNKNOWN = "unknown"
|
STATUS_UNKNOWN = "unknown"
|
||||||
STATUS_STARTED = "started"
|
STATUS_STARTED = "started"
|
||||||
STATUS_STOPPED = "stopped"
|
STATUS_STOPPED = "stopped"
|
||||||
|
|
||||||
#which run types to which runner class
|
# Which run types to which runner class
|
||||||
RUNNER_CLS_MAPPING = {
|
RUNNER_CLS_MAPPING = {
|
||||||
settings.RUN_TYPE_FORK: fork.ForkRunner,
|
settings.RUN_TYPE_FORK: fork.ForkRunner,
|
||||||
settings.RUN_TYPE_UPSTART: upstart.UpstartRunner,
|
settings.RUN_TYPE_UPSTART: upstart.UpstartRunner,
|
||||||
settings.RUN_TYPE_SCREEN: screen.ScreenRunner,
|
settings.RUN_TYPE_SCREEN: screen.ScreenRunner,
|
||||||
}
|
}
|
||||||
|
|
||||||
#where symlinks will go
|
# Where symlinks will go
|
||||||
BASE_LINK_DIR = "/etc"
|
BASE_LINK_DIR = "/etc"
|
||||||
|
|
||||||
|
|
||||||
class ComponentBase(object):
|
class ComponentBase(object):
|
||||||
def __init__(self, component_name, runner,
|
def __init__(self,
|
||||||
root_dir, component_options,
|
desired_subsystems,
|
||||||
instances=None,
|
subsystem_info,
|
||||||
**kwds):
|
runner,
|
||||||
self.component_name = component_name
|
component_dir,
|
||||||
|
all_instances,
|
||||||
|
name,
|
||||||
|
*args,
|
||||||
|
**kargs):
|
||||||
|
|
||||||
|
self.desired_subsystems = desired_subsystems
|
||||||
|
self.instances = all_instances
|
||||||
|
self.component_name = name
|
||||||
|
self.subsystem_info = subsystem_info
|
||||||
|
|
||||||
# The runner has a reference to us, so use a weakref here to
|
# The runner has a reference to us, so use a weakref here to
|
||||||
# avoid breaking garbage collection.
|
# avoid breaking garbage collection.
|
||||||
self.runner = weakref.proxy(runner)
|
self.runner = weakref.proxy(runner)
|
||||||
|
|
||||||
self.root = root_dir
|
|
||||||
self.component_opts = component_options or {}
|
|
||||||
self.instances = instances or {}
|
|
||||||
|
|
||||||
# Parts of the global runner context that we use
|
# Parts of the global runner context that we use
|
||||||
self.cfg = runner.cfg
|
self.cfg = runner.cfg
|
||||||
self.pw_gen = runner.pw_gen
|
self.pw_gen = runner.pw_gen
|
||||||
self.packager = runner.pkg_manager
|
self.packager = runner.pkg_manager
|
||||||
self.distro = runner.distro
|
self.distro = runner.distro
|
||||||
|
|
||||||
self.component_root = sh.joinpths(self.root, component_name)
|
# Required component directories
|
||||||
self.tracedir = sh.joinpths(self.component_root,
|
self.component_dir = component_dir
|
||||||
|
self.trace_dir = sh.joinpths(self.component_dir,
|
||||||
settings.COMPONENT_TRACE_DIR)
|
settings.COMPONENT_TRACE_DIR)
|
||||||
self.appdir = sh.joinpths(self.component_root,
|
self.app_dir = sh.joinpths(self.component_dir,
|
||||||
settings.COMPONENT_APP_DIR)
|
settings.COMPONENT_APP_DIR)
|
||||||
self.cfgdir = sh.joinpths(self.component_root,
|
self.cfg_dir = sh.joinpths(self.component_dir,
|
||||||
settings.COMPONENT_CONFIG_DIR)
|
settings.COMPONENT_CONFIG_DIR)
|
||||||
self.kargs = kwds
|
|
||||||
|
|
||||||
def get_dependencies(self):
|
|
||||||
return self.runner.distro.components[self.component_name].get('dependencies', [])[:]
|
|
||||||
|
|
||||||
def verify(self):
|
def verify(self):
|
||||||
pass
|
# Ensure subsystems are known...
|
||||||
|
knowns = self.known_subsystems()
|
||||||
|
for s in self.desired_subsystems:
|
||||||
|
if s not in knowns:
|
||||||
|
raise RuntimeError("Unknown subsystem %r requested" % (s))
|
||||||
|
for s in self.subsystem_info.keys():
|
||||||
|
if s not in knowns:
|
||||||
|
raise RuntimeError("Unknown subsystem %r provided" % (s))
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return list()
|
||||||
|
|
||||||
def warm_configs(self):
|
def warm_configs(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def is_started(self):
|
def is_started(self):
|
||||||
reader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.START_TRACE))
|
reader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE))
|
||||||
return reader.exists()
|
return reader.exists()
|
||||||
|
|
||||||
def is_installed(self):
|
def is_installed(self):
|
||||||
return tr.TraceReader(tr.trace_fn(self.tracedir, tr.IN_TRACE)).exists()
|
return tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE)).exists()
|
||||||
|
|
||||||
|
|
||||||
class PkgInstallComponent(ComponentBase):
|
class PkgInstallComponent(ComponentBase):
|
||||||
def __init__(self, component_name, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
ComponentBase.__init__(self, component_name, **kargs)
|
ComponentBase.__init__(self, *args, **kargs)
|
||||||
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.tracedir,
|
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.trace_dir,
|
||||||
tr.IN_TRACE)
|
tr.IN_TRACE))
|
||||||
)
|
self.packages = kargs.get('packages', list())
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
def download(self):
|
def download(self):
|
||||||
locations = self._get_download_locations()
|
locations = self._get_download_locations()
|
||||||
base_dir = self.appdir
|
base_dir = self.app_dir
|
||||||
for location_info in locations:
|
for location_info in locations:
|
||||||
uri_tuple = location_info["uri"]
|
uri_tuple = location_info["uri"]
|
||||||
branch_tuple = location_info.get("branch")
|
branch_tuple = location_info.get("branch")
|
||||||
subdir = location_info.get("subdir")
|
sub_dir = location_info.get("subdir")
|
||||||
target_loc = base_dir
|
target_loc = base_dir
|
||||||
if subdir:
|
if sub_dir:
|
||||||
target_loc = sh.joinpths(base_dir, subdir)
|
target_loc = sh.joinpths(base_dir, sub_dir)
|
||||||
branch = None
|
branch = None
|
||||||
if branch_tuple:
|
if branch_tuple:
|
||||||
(cfg_section, cfg_key) = branch_tuple
|
(cfg_section, cfg_key) = branch_tuple
|
||||||
@ -135,11 +148,11 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
raise excp.ConfigException(msg)
|
raise excp.ConfigException(msg)
|
||||||
self.tracewriter.download_happened(target_loc, uri)
|
self.tracewriter.download_happened(target_loc, uri)
|
||||||
dirs_made = down.download(target_loc, uri, branch)
|
dirs_made = down.download(target_loc, uri, branch)
|
||||||
#ensure this is always added so that
|
# Here we ensure this is always added so that
|
||||||
#if a keep old happens then this of course
|
# if a keep old happens then this of course
|
||||||
#won't be recreated, but if u uninstall without keeping old
|
# won't be recreated, but if u uninstall without keeping old
|
||||||
#then this won't be deleted this time around
|
# then this won't be deleted this time around
|
||||||
#adding it in is harmless and willl make sure its removed
|
# adding it in is harmless and will make sure its removed.
|
||||||
dirs_made.append(target_loc)
|
dirs_made.append(target_loc)
|
||||||
self.tracewriter.dirs_made(*dirs_made)
|
self.tracewriter.dirs_made(*dirs_made)
|
||||||
return len(locations)
|
return len(locations)
|
||||||
@ -147,33 +160,39 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
return dict()
|
return dict()
|
||||||
|
|
||||||
|
def _get_packages(self):
|
||||||
|
pkg_list = list(self.packages)
|
||||||
|
for name in self.desired_subsystems:
|
||||||
|
if name in self.subsystem_info:
|
||||||
|
# Todo handle duplicates/version differences?
|
||||||
|
LOG.debug("Extending package list with packages for subsystem %s" % (name))
|
||||||
|
subsystem_pkgs = self.subsystem_info[name].get('packages', list())
|
||||||
|
pkg_list.extend(subsystem_pkgs)
|
||||||
|
return pkg_list
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
LOG.debug('Preparing to install packages for %s',
|
LOG.debug('Preparing to install packages for %s',
|
||||||
self.component_name)
|
self.component_name)
|
||||||
pkgs = self.component_opts.get('packages', [])
|
pkgs = self._get_packages()
|
||||||
if pkgs:
|
if pkgs:
|
||||||
pkgnames = sorted([p['name'] for p in pkgs])
|
pkg_names = set([p['name'] for p in pkgs])
|
||||||
LOG.info("Installing packages (%s).", ", ".join(pkgnames))
|
LOG.info("Setting up %s packages (%s)" % (len(pkg_names), ", ".join(pkg_names)))
|
||||||
# FIXME: We should only record the packages we actually
|
for p in pkgs:
|
||||||
# install without error.
|
self.tracewriter.package_installed(p)
|
||||||
#do this before install just incase it craps out half way through
|
self.packager.install(p)
|
||||||
for pkg in pkgs:
|
|
||||||
self.tracewriter.package_installed(p['name'], pkg)
|
|
||||||
#now actually install
|
|
||||||
self.packager.install_batch(pkgs)
|
|
||||||
else:
|
else:
|
||||||
LOG.info('No packages to install for %s',
|
LOG.info('No packages to install for %s',
|
||||||
self.component_name)
|
self.component_name)
|
||||||
return self.tracedir
|
return self.trace_dir
|
||||||
|
|
||||||
def pre_install(self):
|
def pre_install(self):
|
||||||
pkgs = self.component_opts.get('packages', [])
|
pkgs = self._get_packages()
|
||||||
if pkgs:
|
if pkgs:
|
||||||
mp = self._get_param_map(None)
|
mp = self._get_param_map(None)
|
||||||
self.packager.pre_install(pkgs, mp)
|
self.packager.pre_install(pkgs, mp)
|
||||||
|
|
||||||
def post_install(self):
|
def post_install(self):
|
||||||
pkgs = self.component_opts.get('packages', [])
|
pkgs = self._get_packages()
|
||||||
if pkgs:
|
if pkgs:
|
||||||
mp = self._get_param_map(None)
|
mp = self._get_param_map(None)
|
||||||
self.packager.post_install(pkgs, mp)
|
self.packager.post_install(pkgs, mp)
|
||||||
@ -185,7 +204,7 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
return contents
|
return contents
|
||||||
|
|
||||||
def _get_target_config_name(self, config_fn):
|
def _get_target_config_name(self, config_fn):
|
||||||
return sh.joinpths(self.cfgdir, config_fn)
|
return sh.joinpths(self.cfg_dir, config_fn)
|
||||||
|
|
||||||
def _get_source_config(self, config_fn):
|
def _get_source_config(self, config_fn):
|
||||||
return utils.load_template(self.component_name, config_fn)
|
return utils.load_template(self.component_name, config_fn)
|
||||||
@ -205,13 +224,9 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
if configs:
|
if configs:
|
||||||
LOG.info("Configuring %s files", len(configs))
|
LOG.info("Configuring %s files", len(configs))
|
||||||
for fn in configs:
|
for fn in configs:
|
||||||
#get the params and where it should come from and
|
|
||||||
#where it should go
|
|
||||||
parameters = self._get_param_map(fn)
|
parameters = self._get_param_map(fn)
|
||||||
tgt_fn = self._get_target_config_name(fn)
|
tgt_fn = self._get_target_config_name(fn)
|
||||||
#ensure directory is there (if not created previously)
|
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(sh.dirname(tgt_fn)))
|
self.tracewriter.dirs_made(*sh.mkdirslist(sh.dirname(tgt_fn)))
|
||||||
#now configure it
|
|
||||||
LOG.info("Configuring file %s", fn)
|
LOG.info("Configuring file %s", fn)
|
||||||
(source_fn, contents) = self._get_source_config(fn)
|
(source_fn, contents) = self._get_source_config(fn)
|
||||||
LOG.debug("Replacing parameters in file %s", source_fn)
|
LOG.debug("Replacing parameters in file %s", source_fn)
|
||||||
@ -220,13 +235,15 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
LOG.debug("Applying side-effects of param replacement for template %s", source_fn)
|
LOG.debug("Applying side-effects of param replacement for template %s", source_fn)
|
||||||
contents = self._config_adjust(contents, fn)
|
contents = self._config_adjust(contents, fn)
|
||||||
LOG.info("Writing configuration file %s", tgt_fn)
|
LOG.info("Writing configuration file %s", tgt_fn)
|
||||||
#this trace is used to remove the files configured
|
|
||||||
self.tracewriter.cfg_file_written(sh.write_file(tgt_fn,
|
self.tracewriter.cfg_file_written(sh.write_file(tgt_fn,
|
||||||
contents))
|
contents))
|
||||||
return len(configs)
|
return len(configs)
|
||||||
|
|
||||||
def _configure_symlinks(self):
|
def _configure_symlinks(self):
|
||||||
links = self._get_symlinks()
|
links = self._get_symlinks()
|
||||||
|
# This sort happens so that we link in the correct order
|
||||||
|
# although it might not matter. Either way. We ensure that the right
|
||||||
|
# order happens. Ie /etc/blah link runs before /etc/blah/blah
|
||||||
link_srcs = sorted(links.keys())
|
link_srcs = sorted(links.keys())
|
||||||
link_srcs.reverse()
|
link_srcs.reverse()
|
||||||
for source in link_srcs:
|
for source in link_srcs:
|
||||||
@ -235,8 +252,8 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
LOG.info("Symlinking %s => %s", link, source)
|
LOG.info("Symlinking %s => %s", link, source)
|
||||||
self.tracewriter.dirs_made(*sh.symlink(source, link))
|
self.tracewriter.dirs_made(*sh.symlink(source, link))
|
||||||
self.tracewriter.symlink_made(link)
|
self.tracewriter.symlink_made(link)
|
||||||
except OSError:
|
except OSError as e:
|
||||||
LOG.warn("Symlink %s => %s already exists.", link, source)
|
LOG.warn("Symlink (%s => %s) error (%s)", link, source, e)
|
||||||
return len(links)
|
return len(links)
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
@ -246,26 +263,33 @@ class PkgInstallComponent(ComponentBase):
|
|||||||
|
|
||||||
|
|
||||||
class PythonInstallComponent(PkgInstallComponent):
|
class PythonInstallComponent(PkgInstallComponent):
|
||||||
def __init__(self, component_name, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
PkgInstallComponent.__init__(self, component_name, *args, **kargs)
|
PkgInstallComponent.__init__(self, *args, **kargs)
|
||||||
|
self.pips = kargs.get('pips', list())
|
||||||
|
|
||||||
def _get_python_directories(self):
|
def _get_python_directories(self):
|
||||||
py_dirs = dict()
|
py_dirs = dict()
|
||||||
py_dirs[self.component_name] = self.appdir
|
py_dirs[self.component_name] = self.app_dir
|
||||||
return py_dirs
|
return py_dirs
|
||||||
|
|
||||||
|
def _get_pips(self):
|
||||||
|
pip_list = list(self.pips)
|
||||||
|
for name in self.desired_subsystems:
|
||||||
|
if name in self.subsystem_info:
|
||||||
|
# Todo handle duplicates/version differences?
|
||||||
|
LOG.debug("Extending pip list with pips for subsystem %s" % (name))
|
||||||
|
subsystem_pips = self.subsystem_info[name].get('pips', list())
|
||||||
|
pip_list.extend(subsystem_pips)
|
||||||
|
return pip_list
|
||||||
|
|
||||||
def _install_pips(self):
|
def _install_pips(self):
|
||||||
pips = dict((p['name'], p)
|
pips = self._get_pips()
|
||||||
for p in self.component_opts.get('pips', [])
|
|
||||||
)
|
|
||||||
if pips:
|
if pips:
|
||||||
LOG.info("Setting up %s pips (%s)",
|
pip_names = set([p['name'] for p in pips])
|
||||||
len(pips), ", ".join(pips.keys()))
|
LOG.info("Setting up %s pips (%s)", len(pip_names), ", ".join(pip_names))
|
||||||
#do this before install just incase it craps out half way through
|
for p in pips:
|
||||||
for name in pips.keys():
|
self.tracewriter.pip_installed(p)
|
||||||
self.tracewriter.pip_installed(name, pips.get(name))
|
pip.install(p, self.distro)
|
||||||
#now install
|
|
||||||
pip.install(pips, self.distro)
|
|
||||||
|
|
||||||
def _install_python_setups(self):
|
def _install_python_setups(self):
|
||||||
pydirs = self._get_python_directories()
|
pydirs = self._get_python_directories()
|
||||||
@ -273,18 +297,17 @@ class PythonInstallComponent(PkgInstallComponent):
|
|||||||
LOG.info("Setting up %s python directories (%s)",
|
LOG.info("Setting up %s python directories (%s)",
|
||||||
len(pydirs), pydirs)
|
len(pydirs), pydirs)
|
||||||
for (name, wkdir) in pydirs.items():
|
for (name, wkdir) in pydirs.items():
|
||||||
working_dir = wkdir or self.appdir
|
working_dir = wkdir or self.app_dir
|
||||||
#ensure working dir is there
|
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(working_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(working_dir))
|
||||||
#do this before write just incase it craps out half way through
|
|
||||||
self.tracewriter.py_installed(name, working_dir)
|
self.tracewriter.py_installed(name, working_dir)
|
||||||
#now actually do it
|
|
||||||
(stdout, stderr) = sh.execute(*PY_INSTALL,
|
(stdout, stderr) = sh.execute(*PY_INSTALL,
|
||||||
cwd=working_dir,
|
cwd=working_dir,
|
||||||
run_as_root=True)
|
run_as_root=True)
|
||||||
py_trace_name = "%s-%s" % (tr.PY_TRACE, name)
|
py_trace_name = "%s-%s" % (tr.PY_TRACE, name)
|
||||||
py_writer = tr.TraceWriter(tr.trace_fn(self.tracedir,
|
py_writer = tr.TraceWriter(tr.trace_fn(self.trace_dir,
|
||||||
py_trace_name))
|
py_trace_name))
|
||||||
|
# Format or json encoding isn't really needed here since this is
|
||||||
|
# more just for information output/lookup if desired.
|
||||||
py_writer.trace("CMD", " ".join(PY_INSTALL))
|
py_writer.trace("CMD", " ".join(PY_INSTALL))
|
||||||
py_writer.trace("STDOUT", stdout)
|
py_writer.trace("STDOUT", stdout)
|
||||||
py_writer.trace("STDERR", stderr)
|
py_writer.trace("STDERR", stderr)
|
||||||
@ -301,18 +324,18 @@ class PythonInstallComponent(PkgInstallComponent):
|
|||||||
|
|
||||||
|
|
||||||
class PkgUninstallComponent(ComponentBase):
|
class PkgUninstallComponent(ComponentBase):
|
||||||
def __init__(self, component_name, keep_old=None, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
ComponentBase.__init__(self, component_name, **kargs)
|
ComponentBase.__init__(self, *args, **kargs)
|
||||||
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir,
|
self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir,
|
||||||
tr.IN_TRACE))
|
tr.IN_TRACE))
|
||||||
self.keep_old = keep_old
|
self.keep_old = kargs.get('keep_old')
|
||||||
|
|
||||||
def unconfigure(self):
|
def unconfigure(self):
|
||||||
if not self.keep_old:
|
if not self.keep_old:
|
||||||
#TODO this may not be the best solution siance we might
|
# TODO this may not be the best solution siance we might
|
||||||
#actually want to remove config files but since most
|
# actually want to remove config files but since most
|
||||||
#config files can be regenerated this should be fine (some
|
# config files can be regenerated this should be fine (some
|
||||||
#can not though) so this is why we need to keep them
|
# can not though) so this is why we need to keep them.
|
||||||
self._unconfigure_files()
|
self._unconfigure_files()
|
||||||
self._unconfigure_links()
|
self._unconfigure_links()
|
||||||
self._unconfigure_runners()
|
self._unconfigure_runners()
|
||||||
@ -321,7 +344,7 @@ class PkgUninstallComponent(ComponentBase):
|
|||||||
if RUNNER_CLS_MAPPING:
|
if RUNNER_CLS_MAPPING:
|
||||||
LOG.info("Unconfiguring %s runners.", len(RUNNER_CLS_MAPPING))
|
LOG.info("Unconfiguring %s runners.", len(RUNNER_CLS_MAPPING))
|
||||||
for (_, cls) in RUNNER_CLS_MAPPING.items():
|
for (_, cls) in RUNNER_CLS_MAPPING.items():
|
||||||
instance = cls(self.cfg, self.component_name, self.tracedir)
|
instance = cls(self.cfg, self.component_name, self.trace_dir)
|
||||||
instance.unconfigure()
|
instance.unconfigure()
|
||||||
|
|
||||||
def _unconfigure_links(self):
|
def _unconfigure_links(self):
|
||||||
@ -354,11 +377,11 @@ class PkgUninstallComponent(ComponentBase):
|
|||||||
def _uninstall_pkgs(self):
|
def _uninstall_pkgs(self):
|
||||||
pkgsfull = self.tracereader.packages_installed()
|
pkgsfull = self.tracereader.packages_installed()
|
||||||
if pkgsfull:
|
if pkgsfull:
|
||||||
LOG.info("Potentially removing %s packages (%s)",
|
LOG.info("Potentially removing %s packages",
|
||||||
len(pkgsfull), ", ".join(sorted(pkgsfull.keys())))
|
len(pkgsfull))
|
||||||
which_removed = self.packager.remove_batch(pkgsfull)
|
which_removed = self.packager.remove_batch(pkgsfull)
|
||||||
LOG.info("Actually removed %s packages (%s)",
|
LOG.info("Actually removed %s packages (%s)",
|
||||||
len(which_removed), ", ".join(sorted(which_removed)))
|
len(which_removed), ", ".join(which_removed))
|
||||||
|
|
||||||
def _uninstall_touched_files(self):
|
def _uninstall_touched_files(self):
|
||||||
filestouched = self.tracereader.files_touched()
|
filestouched = self.tracereader.files_touched()
|
||||||
@ -386,8 +409,8 @@ class PkgUninstallComponent(ComponentBase):
|
|||||||
|
|
||||||
|
|
||||||
class PythonUninstallComponent(PkgUninstallComponent):
|
class PythonUninstallComponent(PkgUninstallComponent):
|
||||||
def __init__(self, component_name, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
PkgUninstallComponent.__init__(self, component_name, *args, **kargs)
|
PkgUninstallComponent.__init__(self, *args, **kargs)
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
self._uninstall_python()
|
self._uninstall_python()
|
||||||
@ -397,8 +420,9 @@ class PythonUninstallComponent(PkgUninstallComponent):
|
|||||||
def _uninstall_pips(self):
|
def _uninstall_pips(self):
|
||||||
pips = self.tracereader.pips_installed()
|
pips = self.tracereader.pips_installed()
|
||||||
if pips:
|
if pips:
|
||||||
LOG.info("Uninstalling %s pips.", len(pips))
|
names = set([p['name'] for p in pips])
|
||||||
pip.uninstall(pips, self.distro)
|
LOG.info("Uninstalling %s python packages (%s)" % (len(names), ", ".join(names)))
|
||||||
|
pip.uninstall_batch(pips, self.distro)
|
||||||
|
|
||||||
def _uninstall_python(self):
|
def _uninstall_python(self):
|
||||||
pylisting = self.tracereader.py_listing()
|
pylisting = self.tracereader.py_listing()
|
||||||
@ -409,10 +433,10 @@ class PythonUninstallComponent(PkgUninstallComponent):
|
|||||||
|
|
||||||
|
|
||||||
class ProgramRuntime(ComponentBase):
|
class ProgramRuntime(ComponentBase):
|
||||||
def __init__(self, component_name, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
ComponentBase.__init__(self, component_name, **kargs)
|
ComponentBase.__init__(self, *args, **kargs)
|
||||||
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.tracedir, tr.START_TRACE))
|
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.trace_dir, tr.START_TRACE))
|
||||||
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.START_TRACE))
|
self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE))
|
||||||
|
|
||||||
def _get_apps_to_start(self):
|
def _get_apps_to_start(self):
|
||||||
return list()
|
return list()
|
||||||
@ -422,7 +446,7 @@ class ProgramRuntime(ComponentBase):
|
|||||||
|
|
||||||
def _get_param_map(self, app_name):
|
def _get_param_map(self, app_name):
|
||||||
return {
|
return {
|
||||||
'ROOT': self.appdir,
|
'ROOT': self.app_dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
def pre_start(self):
|
def pre_start(self):
|
||||||
@ -435,12 +459,12 @@ class ProgramRuntime(ComponentBase):
|
|||||||
# First make a pass and make sure all runtime (e.g. upstart)
|
# First make a pass and make sure all runtime (e.g. upstart)
|
||||||
# config files are in place....
|
# config files are in place....
|
||||||
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
|
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
|
||||||
instance = cls(self.cfg, self.component_name, self.tracedir)
|
instance = cls(self.cfg, self.component_name, self.trace_dir)
|
||||||
tot_am = 0
|
tot_am = 0
|
||||||
for app_info in self._get_apps_to_start():
|
for app_info in self._get_apps_to_start():
|
||||||
app_name = app_info["name"]
|
app_name = app_info["name"]
|
||||||
app_pth = app_info.get("path", app_name)
|
app_pth = app_info.get("path", app_name)
|
||||||
app_dir = app_info.get("app_dir", self.appdir)
|
app_dir = app_info.get("app_dir", self.app_dir)
|
||||||
# Adjust the program options now that we have real locations
|
# Adjust the program options now that we have real locations
|
||||||
program_opts = utils.param_replace_list(
|
program_opts = utils.param_replace_list(
|
||||||
self._get_app_options(app_name),
|
self._get_app_options(app_name),
|
||||||
@ -458,12 +482,12 @@ class ProgramRuntime(ComponentBase):
|
|||||||
def start(self):
|
def start(self):
|
||||||
# Select how we are going to start it
|
# Select how we are going to start it
|
||||||
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
|
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
|
||||||
instance = cls(self.cfg, self.component_name, self.tracedir)
|
instance = cls(self.cfg, self.component_name, self.trace_dir)
|
||||||
am_started = 0
|
am_started = 0
|
||||||
for app_info in self._get_apps_to_start():
|
for app_info in self._get_apps_to_start():
|
||||||
app_name = app_info["name"]
|
app_name = app_info["name"]
|
||||||
app_pth = app_info.get("path", app_name)
|
app_pth = app_info.get("path", app_name)
|
||||||
app_dir = app_info.get("app_dir", self.appdir)
|
app_dir = app_info.get("app_dir", self.app_dir)
|
||||||
# Adjust the program options now that we have real locations
|
# Adjust the program options now that we have real locations
|
||||||
program_opts = utils.param_replace_list(
|
program_opts = utils.param_replace_list(
|
||||||
self._get_app_options(app_name),
|
self._get_app_options(app_name),
|
||||||
@ -500,7 +524,7 @@ class ProgramRuntime(ComponentBase):
|
|||||||
else:
|
else:
|
||||||
killer = killcls(self.cfg,
|
killer = killcls(self.cfg,
|
||||||
self.component_name,
|
self.component_name,
|
||||||
self.tracedir,
|
self.trace_dir,
|
||||||
)
|
)
|
||||||
killer_instances[killcls] = killer
|
killer_instances[killcls] = killer
|
||||||
to_kill.append((app_name, killer))
|
to_kill.append((app_name, killer))
|
||||||
@ -526,14 +550,14 @@ class ProgramRuntime(ComponentBase):
|
|||||||
|
|
||||||
|
|
||||||
class PythonRuntime(ProgramRuntime):
|
class PythonRuntime(ProgramRuntime):
|
||||||
def __init__(self, component_name, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
ProgramRuntime.__init__(self, component_name, *args, **kargs)
|
ProgramRuntime.__init__(self, *args, **kargs)
|
||||||
|
|
||||||
|
|
||||||
class EmptyRuntime(ComponentBase):
|
class EmptyRuntime(ComponentBase):
|
||||||
def __init__(self, component_name, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
ComponentBase.__init__(self, component_name, **kargs)
|
ComponentBase.__init__(self, *args, **kargs)
|
||||||
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.IN_TRACE))
|
self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE))
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
return 0
|
return 0
|
||||||
|
@ -21,29 +21,25 @@ from devstack import settings
|
|||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
#id
|
|
||||||
# FIXME: This should probably come from the persona
|
|
||||||
TYPE = settings.DB
|
|
||||||
LOG = logging.getLogger("devstack.components.db")
|
LOG = logging.getLogger("devstack.components.db")
|
||||||
|
|
||||||
#used for special setups
|
# How long we wait before using the database after a restart
|
||||||
MYSQL = 'mysql'
|
|
||||||
START_WAIT_TIME = settings.WAIT_ALIVE_SECS
|
START_WAIT_TIME = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#need to reset pw to blank since this distributions don't seem to
|
# Need to reset pw to blank since this distributions don't seem to
|
||||||
#always reset it when u uninstall the db
|
# always reset it when u uninstall the db
|
||||||
RESET_BASE_PW = ''
|
RESET_BASE_PW = ''
|
||||||
|
|
||||||
#links about how to reset if it fails
|
# Links about how to reset if we fail to set the PW
|
||||||
SQL_RESET_PW_LINKS = [
|
SQL_RESET_PW_LINKS = [
|
||||||
'https://help.ubuntu.com/community/MysqlPasswordReset',
|
'https://help.ubuntu.com/community/MysqlPasswordReset',
|
||||||
'http://dev.mysql.com/doc/refman/5.0/en/resetting-permissions.html',
|
'http://dev.mysql.com/doc/refman/5.0/en/resetting-permissions.html',
|
||||||
]
|
]
|
||||||
|
|
||||||
#used as a generic error message
|
# Used as a generic error message
|
||||||
BASE_ERROR = 'Currently we do not know how to [%s] for database type [%s]'
|
BASE_ERROR = 'Currently we do not know how to [%s] for database type [%s]'
|
||||||
|
|
||||||
#config keys we warm up so u won't be prompted later
|
# PW keys we warm up so u won't be prompted later
|
||||||
PASSWORD_PROMPT = 'the database user'
|
PASSWORD_PROMPT = 'the database user'
|
||||||
WARMUP_PWS = [('sql', PASSWORD_PROMPT)]
|
WARMUP_PWS = [('sql', PASSWORD_PROMPT)]
|
||||||
|
|
||||||
@ -59,7 +55,7 @@ class DBUninstaller(comp.PkgUninstallComponent):
|
|||||||
|
|
||||||
def pre_uninstall(self):
|
def pre_uninstall(self):
|
||||||
dbtype = self.cfg.get("db", "type")
|
dbtype = self.cfg.get("db", "type")
|
||||||
dbactions = self.distro.commands[dbtype]
|
dbactions = self.distro.get_command(dbtype, quiet=True)
|
||||||
try:
|
try:
|
||||||
if dbactions:
|
if dbactions:
|
||||||
LOG.info(("Attempting to reset your db password to \"%s\" so"
|
LOG.info(("Attempting to reset your db password to \"%s\" so"
|
||||||
@ -87,8 +83,8 @@ class DBInstaller(comp.PkgInstallComponent):
|
|||||||
self.runtime = DBRuntime(*args, **kargs)
|
self.runtime = DBRuntime(*args, **kargs)
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
#this dictionary will be used for parameter replacement
|
# This dictionary will be used for parameter replacement
|
||||||
#in pre-install and post-install sections
|
# In pre-install and post-install sections
|
||||||
host_ip = self.cfg.get('host', 'ip')
|
host_ip = self.cfg.get('host', 'ip')
|
||||||
out = {
|
out = {
|
||||||
'PASSWORD': self.pw_gen.get_password("sql", PASSWORD_PROMPT),
|
'PASSWORD': self.pw_gen.get_password("sql", PASSWORD_PROMPT),
|
||||||
@ -104,38 +100,19 @@ class DBInstaller(comp.PkgInstallComponent):
|
|||||||
self.pw_gen.get_password(key, prompt)
|
self.pw_gen.get_password(key, prompt)
|
||||||
|
|
||||||
def _configure_db_confs(self):
|
def _configure_db_confs(self):
|
||||||
dbtype = self.cfg.get("db", "type")
|
pass
|
||||||
#TODO: use separate classes in devstack.distros.$distro.db and
|
|
||||||
# specify them in the yaml file
|
|
||||||
if self.distro.name == settings.RHEL6 and dbtype == MYSQL:
|
|
||||||
LOG.info("Fixing up %s mysql configs." % (settings.RHEL6))
|
|
||||||
fc = sh.load_file('/etc/my.cnf')
|
|
||||||
lines = fc.splitlines()
|
|
||||||
new_lines = list()
|
|
||||||
for line in lines:
|
|
||||||
if line.startswith('skip-grant-tables'):
|
|
||||||
line = '#' + line
|
|
||||||
new_lines.append(line)
|
|
||||||
fc = utils.joinlinesep(*new_lines)
|
|
||||||
with sh.Rooted(True):
|
|
||||||
sh.write_file('/etc/my.cnf', fc)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(
|
|
||||||
'Do not know how to configure db confs for %s' %
|
|
||||||
self.distro.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def post_install(self):
|
def post_install(self):
|
||||||
comp.PkgInstallComponent.post_install(self)
|
comp.PkgInstallComponent.post_install(self)
|
||||||
|
|
||||||
#fix up the db configs
|
# Fix up the db configs
|
||||||
self._configure_db_confs()
|
self._configure_db_confs()
|
||||||
|
|
||||||
#extra actions to ensure we are granted access
|
# Extra actions to ensure we are granted access
|
||||||
dbtype = self.cfg.get("db", "type")
|
dbtype = self.cfg.get("db", "type")
|
||||||
dbactions = self.distro.commands[dbtype]
|
dbactions = self.distro.get_command(dbtype, quiet=True)
|
||||||
|
|
||||||
#set your password
|
# Set your password
|
||||||
try:
|
try:
|
||||||
if dbactions:
|
if dbactions:
|
||||||
pwd_cmd = dbactions.get('set_pwd')
|
pwd_cmd = dbactions.get('set_pwd')
|
||||||
@ -155,7 +132,7 @@ class DBInstaller(comp.PkgInstallComponent):
|
|||||||
LOG.warn(("Couldn't set your db password. It might have already been "
|
LOG.warn(("Couldn't set your db password. It might have already been "
|
||||||
"set by a previous process."))
|
"set by a previous process."))
|
||||||
|
|
||||||
#ensure access granted
|
# Ensure access granted
|
||||||
if dbactions:
|
if dbactions:
|
||||||
grant_cmd = dbactions.get('grant_all')
|
grant_cmd = dbactions.get('grant_all')
|
||||||
if grant_cmd:
|
if grant_cmd:
|
||||||
@ -168,8 +145,8 @@ class DBInstaller(comp.PkgInstallComponent):
|
|||||||
'USER': user,
|
'USER': user,
|
||||||
}
|
}
|
||||||
cmds = [{'cmd': grant_cmd}]
|
cmds = [{'cmd': grant_cmd}]
|
||||||
#shell seems to be needed here
|
# Shell seems to be needed here
|
||||||
#since python escapes this to much...
|
# since python escapes this to much...
|
||||||
utils.execute_template(*cmds, params=params, shell=True)
|
utils.execute_template(*cmds, params=params, shell=True)
|
||||||
|
|
||||||
|
|
||||||
@ -179,11 +156,7 @@ class DBRuntime(comp.EmptyRuntime):
|
|||||||
|
|
||||||
def _get_run_actions(self, act, exception_cls):
|
def _get_run_actions(self, act, exception_cls):
|
||||||
dbtype = self.cfg.get("db", "type")
|
dbtype = self.cfg.get("db", "type")
|
||||||
type_actions = self.distro.commands[dbtype]
|
distro_options = self.distro.get_command(dbtype)
|
||||||
if type_actions is None:
|
|
||||||
msg = BASE_ERROR % (act, dbtype)
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
distro_options = self.distro.commands[dbtype]
|
|
||||||
if distro_options is None:
|
if distro_options is None:
|
||||||
msg = BASE_ERROR % (act, dbtype)
|
msg = BASE_ERROR % (act, dbtype)
|
||||||
raise NotImplementedError(msg)
|
raise NotImplementedError(msg)
|
||||||
@ -241,7 +214,7 @@ class DBRuntime(comp.EmptyRuntime):
|
|||||||
|
|
||||||
def drop_db(cfg, pw_gen, distro, dbname):
|
def drop_db(cfg, pw_gen, distro, dbname):
|
||||||
dbtype = cfg.get("db", "type")
|
dbtype = cfg.get("db", "type")
|
||||||
dbactions = distro.commands[dbtype]
|
dbactions = distro.get_command(dbtype)
|
||||||
if dbactions and dbactions.get('drop_db'):
|
if dbactions and dbactions.get('drop_db'):
|
||||||
dropcmd = dbactions.get('drop_db')
|
dropcmd = dbactions.get('drop_db')
|
||||||
params = dict()
|
params = dict()
|
||||||
@ -261,7 +234,7 @@ def drop_db(cfg, pw_gen, distro, dbname):
|
|||||||
|
|
||||||
def create_db(cfg, pw_gen, distro, dbname):
|
def create_db(cfg, pw_gen, distro, dbname):
|
||||||
dbtype = cfg.get("db", "type")
|
dbtype = cfg.get("db", "type")
|
||||||
dbactions = distro.commands[dbtype]
|
dbactions = distro.get_command(dbtype)
|
||||||
if dbactions and dbactions.get('create_db'):
|
if dbactions and dbactions.get('create_db'):
|
||||||
createcmd = dbactions.get('create_db')
|
createcmd = dbactions.get('create_db')
|
||||||
params = dict()
|
params = dict()
|
||||||
|
@ -27,11 +27,9 @@ from devstack.components import keystone
|
|||||||
|
|
||||||
from devstack.image import creator
|
from devstack.image import creator
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.GLANCE
|
|
||||||
LOG = logging.getLogger("devstack.components.glance")
|
LOG = logging.getLogger("devstack.components.glance")
|
||||||
|
|
||||||
#config files/sections
|
# Config files/sections
|
||||||
API_CONF = "glance-api.conf"
|
API_CONF = "glance-api.conf"
|
||||||
REG_CONF = "glance-registry.conf"
|
REG_CONF = "glance-registry.conf"
|
||||||
API_PASTE_CONF = 'glance-api-paste.ini'
|
API_PASTE_CONF = 'glance-api-paste.ini'
|
||||||
@ -47,33 +45,32 @@ CONFIGS = [API_CONF, REG_CONF, API_PASTE_CONF,
|
|||||||
READ_CONFIGS = [API_CONF, REG_CONF, API_PASTE_CONF,
|
READ_CONFIGS = [API_CONF, REG_CONF, API_PASTE_CONF,
|
||||||
REG_PASTE_CONF, SCRUB_CONF, SCRUB_PASTE_CONF]
|
REG_PASTE_CONF, SCRUB_CONF, SCRUB_PASTE_CONF]
|
||||||
|
|
||||||
#reg, api are here as possible subcomponents
|
# Reg, api, scrub are here as possible subsystems
|
||||||
GAPI = "api"
|
GAPI = "api"
|
||||||
GREG = "reg"
|
GREG = "reg"
|
||||||
GSCR = 'scrub'
|
GSCR = 'scrub'
|
||||||
|
|
||||||
#this db will be dropped and created
|
# This db will be dropped and created
|
||||||
DB_NAME = "glance"
|
DB_NAME = "glance"
|
||||||
|
|
||||||
#special subcomponents/options that are used in starting to know that images should be uploaded
|
# How long to wait before attempting image upload
|
||||||
NO_IMG_START = "no-image-upload"
|
|
||||||
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#what to start
|
# What applications to start
|
||||||
APP_OPTIONS = {
|
APP_OPTIONS = {
|
||||||
'glance-api': ['--config-file', sh.joinpths('%ROOT%', "etc", API_CONF)],
|
'glance-api': ['--config-file', sh.joinpths('%ROOT%', "etc", API_CONF)],
|
||||||
'glance-registry': ['--config-file', sh.joinpths('%ROOT%', "etc", REG_CONF)],
|
'glance-registry': ['--config-file', sh.joinpths('%ROOT%', "etc", REG_CONF)],
|
||||||
'glance-scrubber': ['--config-file', sh.joinpths('%ROOT%', "etc", REG_CONF)],
|
'glance-scrubber': ['--config-file', sh.joinpths('%ROOT%', "etc", REG_CONF)],
|
||||||
}
|
}
|
||||||
|
|
||||||
#how the subcompoent small name translates to an actual app
|
# How the subcompoent small name translates to an actual app
|
||||||
SUB_TO_APP = {
|
SUB_TO_APP = {
|
||||||
GAPI: 'glance-api',
|
GAPI: 'glance-api',
|
||||||
GREG: 'glance-registry',
|
GREG: 'glance-registry',
|
||||||
GSCR: 'glance-scrubber',
|
GSCR: 'glance-scrubber',
|
||||||
}
|
}
|
||||||
|
|
||||||
#subdirs of the downloaded
|
# Subdirs of the downloaded (we are overriding the original)
|
||||||
CONFIG_DIR = 'etc'
|
CONFIG_DIR = 'etc'
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
|
|
||||||
@ -81,13 +78,16 @@ BIN_DIR = 'bin'
|
|||||||
class GlanceUninstaller(comp.PythonUninstallComponent):
|
class GlanceUninstaller(comp.PythonUninstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return SUB_TO_APP.keys()
|
||||||
|
|
||||||
|
|
||||||
class GlanceInstaller(comp.PythonInstallComponent):
|
class GlanceInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
places = list()
|
places = list()
|
||||||
@ -97,6 +97,9 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
|||||||
})
|
})
|
||||||
return places
|
return places
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return SUB_TO_APP.keys()
|
||||||
|
|
||||||
def _get_config_files(self):
|
def _get_config_files(self):
|
||||||
return list(CONFIGS)
|
return list(CONFIGS)
|
||||||
|
|
||||||
@ -111,22 +114,22 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _get_source_config(self, config_fn):
|
def _get_source_config(self, config_fn):
|
||||||
if config_fn == POLICY_JSON:
|
if config_fn == POLICY_JSON:
|
||||||
fn = sh.joinpths(self.cfgdir, POLICY_JSON)
|
fn = sh.joinpths(self.cfg_dir, POLICY_JSON)
|
||||||
contents = sh.load_file(fn)
|
contents = sh.load_file(fn)
|
||||||
return (fn, contents)
|
return (fn, contents)
|
||||||
elif config_fn == LOGGING_CONF:
|
elif config_fn == LOGGING_CONF:
|
||||||
fn = sh.joinpths(self.cfgdir, LOGGING_SOURCE_FN)
|
fn = sh.joinpths(self.cfg_dir, LOGGING_SOURCE_FN)
|
||||||
contents = sh.load_file(fn)
|
contents = sh.load_file(fn)
|
||||||
return (fn, contents)
|
return (fn, contents)
|
||||||
return comp.PythonInstallComponent._get_source_config(self, config_fn)
|
return comp.PythonInstallComponent._get_source_config(self, config_fn)
|
||||||
|
|
||||||
def _config_adjust(self, contents, name):
|
def _config_adjust(self, contents, name):
|
||||||
#even bother opening??
|
# Even bother opening??
|
||||||
if name not in READ_CONFIGS:
|
if name not in READ_CONFIGS:
|
||||||
return contents
|
return contents
|
||||||
#use config parser and
|
# Use config parser and
|
||||||
#then extract known configs that
|
# then extract known configs that
|
||||||
#will need locations/directories/files made (or touched)...
|
# will need locations/directories/files made (or touched)...
|
||||||
with io.BytesIO(contents) as stream:
|
with io.BytesIO(contents) as stream:
|
||||||
config = cfg.IgnoreMissingConfigParser()
|
config = cfg.IgnoreMissingConfigParser()
|
||||||
config.readfp(stream)
|
config.readfp(stream)
|
||||||
@ -135,15 +138,15 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
|||||||
if cache_dir:
|
if cache_dir:
|
||||||
LOG.info("Ensuring image cache data directory %s exists "\
|
LOG.info("Ensuring image cache data directory %s exists "\
|
||||||
"(and is empty)" % (cache_dir))
|
"(and is empty)" % (cache_dir))
|
||||||
#destroy then recreate the image cache directory
|
# Destroy then recreate the image cache directory
|
||||||
sh.deldir(cache_dir)
|
sh.deldir(cache_dir)
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(cache_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(cache_dir))
|
||||||
if config.get('default', 'default_store') == 'file':
|
if config.get('default', 'default_store') == 'file':
|
||||||
file_dir = config.get('default', 'filesystem_store_datadir')
|
file_dir = config.get('default', 'filesystem_store_datadir')
|
||||||
if file_dir:
|
if file_dir:
|
||||||
LOG.info("Ensuring file system store directory %s exists and is empty." % (file_dir))
|
LOG.info("Ensuring file system store directory %s exists and is empty." % (file_dir))
|
||||||
#delete existing images
|
# Delete existing images
|
||||||
#and recreate the image directory
|
# and recreate the image directory
|
||||||
sh.deldir(file_dir)
|
sh.deldir(file_dir)
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(file_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(file_dir))
|
||||||
log_filename = config.get('default', 'log_file')
|
log_filename = config.get('default', 'log_file')
|
||||||
@ -153,24 +156,24 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
|||||||
if log_dir:
|
if log_dir:
|
||||||
LOG.info("Ensuring log directory %s exists." % (log_dir))
|
LOG.info("Ensuring log directory %s exists." % (log_dir))
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(log_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(log_dir))
|
||||||
#destroy then recreate it (the log file)
|
# Destroy then recreate it (the log file)
|
||||||
sh.unlink(log_filename)
|
sh.unlink(log_filename)
|
||||||
self.tracewriter.file_touched(sh.touch_file(log_filename))
|
self.tracewriter.file_touched(sh.touch_file(log_filename))
|
||||||
if config.getboolean('default', 'delayed_delete'):
|
if config.getboolean('default', 'delayed_delete'):
|
||||||
data_dir = config.get('default', 'scrubber_datadir')
|
data_dir = config.get('default', 'scrubber_datadir')
|
||||||
if data_dir:
|
if data_dir:
|
||||||
LOG.info("Ensuring scrubber data dir %s exists and is empty." % (data_dir))
|
LOG.info("Ensuring scrubber data dir %s exists and is empty." % (data_dir))
|
||||||
#destroy then recreate the scrubber data directory
|
# Destroy then recreate the scrubber data directory
|
||||||
sh.deldir(data_dir)
|
sh.deldir(data_dir)
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(data_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(data_dir))
|
||||||
#nothing modified so just return the original
|
# Nothing modified so just return the original
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
#this dict will be used to fill in the configuration
|
# This dict will be used to fill in the configuration
|
||||||
#params with actual values
|
# params with actual values
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['DEST'] = self.appdir
|
mp['DEST'] = self.app_dir
|
||||||
mp['SYSLOG'] = self.cfg.getboolean("default", "syslog")
|
mp['SYSLOG'] = self.cfg.getboolean("default", "syslog")
|
||||||
mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
||||||
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
|
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
|
||||||
@ -182,14 +185,19 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
|||||||
class GlanceRuntime(comp.PythonRuntime):
|
class GlanceRuntime(comp.PythonRuntime):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonRuntime.__init__(self, *args, **kargs)
|
comp.PythonRuntime.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return SUB_TO_APP.keys()
|
||||||
|
|
||||||
def _get_apps_to_start(self):
|
def _get_apps_to_start(self):
|
||||||
apps = [{'name': app_name,
|
apps = list()
|
||||||
'path': sh.joinpths(self.appdir, BIN_DIR, app_name),
|
for subsys in self.desired_subsystems:
|
||||||
}
|
app = dict()
|
||||||
for app_name in APP_OPTIONS.keys()
|
app['name'] = SUB_TO_APP[subsys]
|
||||||
]
|
app['path'] = sh.joinpths(self.bin_dir, app['name'])
|
||||||
|
apps.append(app)
|
||||||
return apps
|
return apps
|
||||||
|
|
||||||
def _get_app_options(self, app):
|
def _get_app_options(self, app):
|
||||||
@ -197,7 +205,7 @@ class GlanceRuntime(comp.PythonRuntime):
|
|||||||
|
|
||||||
def post_start(self):
|
def post_start(self):
|
||||||
comp.PythonRuntime.post_start(self)
|
comp.PythonRuntime.post_start(self)
|
||||||
#install any images that need activating...
|
# Install any images that need activating...
|
||||||
# TODO: make this less cheesy - need to wait till glance goes online
|
# TODO: make this less cheesy - need to wait till glance goes online
|
||||||
LOG.info("Waiting %s seconds so that glance can start up before image install." % (WAIT_ONLINE_TO))
|
LOG.info("Waiting %s seconds so that glance can start up before image install." % (WAIT_ONLINE_TO))
|
||||||
sh.sleep(WAIT_ONLINE_TO)
|
sh.sleep(WAIT_ONLINE_TO)
|
||||||
|
@ -21,50 +21,37 @@ from devstack import settings
|
|||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.HORIZON
|
|
||||||
LOG = logging.getLogger("devstack.components.horizon")
|
LOG = logging.getLogger("devstack.components.horizon")
|
||||||
|
|
||||||
#actual dir names
|
# Actual dir names
|
||||||
ROOT_HORIZON = 'horizon'
|
ROOT_HORIZON = 'horizon'
|
||||||
ROOT_DASH = 'openstack_dashboard'
|
ROOT_DASH = 'openstack_dashboard'
|
||||||
|
|
||||||
#name used for python install trace
|
# Name used for python install trace
|
||||||
HORIZON_NAME = ROOT_HORIZON
|
HORIZON_NAME = ROOT_HORIZON
|
||||||
DASH_NAME = 'dashboard'
|
DASH_NAME = 'dashboard'
|
||||||
|
|
||||||
#config files messed with
|
# Config files messed with
|
||||||
HORIZON_PY_CONF = "horizon_settings.py"
|
HORIZON_PY_CONF = "horizon_settings.py"
|
||||||
HORIZON_PY_CONF_TGT = ['local', 'local_settings.py']
|
HORIZON_PY_CONF_TGT = ['local', 'local_settings.py']
|
||||||
HORIZON_APACHE_CONF = '000-default'
|
HORIZON_APACHE_CONF = '000-default'
|
||||||
CONFIGS = [HORIZON_PY_CONF, HORIZON_APACHE_CONF]
|
CONFIGS = [HORIZON_PY_CONF, HORIZON_APACHE_CONF]
|
||||||
|
|
||||||
#http://wiki.apache.org/httpd/DistrosDefaultLayout
|
# DB sync that needs to happen for horizon
|
||||||
|
|
||||||
#db sync that needs to happen for horizon
|
|
||||||
DB_SYNC_CMD = ['python', 'manage.py', 'syncdb']
|
DB_SYNC_CMD = ['python', 'manage.py', 'syncdb']
|
||||||
|
|
||||||
#special apache directory (TODO describe more about this)
|
# Special apache directory (TODO describe more about this)
|
||||||
BLACKHOLE_DIR = '.blackhole'
|
BLACKHOLE_DIR = '.blackhole'
|
||||||
|
|
||||||
|
# Other apache settings
|
||||||
APACHE_ERROR_LOG_FN = "error.log"
|
APACHE_ERROR_LOG_FN = "error.log"
|
||||||
APACHE_ACCESS_LOG_FN = "access.log"
|
APACHE_ACCESS_LOG_FN = "access.log"
|
||||||
APACHE_DEF_PORT = 80
|
APACHE_DEF_PORT = 80
|
||||||
|
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
# Users which apache may not like starting as..
|
||||||
APACHE_FIXUPS = {
|
|
||||||
'SOCKET_CONF': "/etc/httpd/conf.d/wsgi-socket-prefix.conf",
|
|
||||||
'HTTPD_CONF': '/etc/httpd/conf/httpd.conf',
|
|
||||||
}
|
|
||||||
APACHE_FIXUPS_DISTROS = [settings.RHEL6, settings.FEDORA16]
|
|
||||||
|
|
||||||
#for when quantum client is not need we need some fake files so python doesn't croak
|
|
||||||
FAKE_QUANTUM_FILES = ['__init__.py', 'client.py']
|
|
||||||
|
|
||||||
#users which apache may not like starting as
|
|
||||||
BAD_APACHE_USERS = ['root']
|
BAD_APACHE_USERS = ['root']
|
||||||
|
|
||||||
#apache logs will go here
|
# Apache logs will go here
|
||||||
LOGS_DIR = "logs"
|
LOGS_DIR = "logs"
|
||||||
|
|
||||||
|
|
||||||
@ -76,9 +63,9 @@ class HorizonUninstaller(comp.PythonUninstallComponent):
|
|||||||
class HorizonInstaller(comp.PythonInstallComponent):
|
class HorizonInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.horizon_dir = sh.joinpths(self.appdir, ROOT_HORIZON)
|
self.horizon_dir = sh.joinpths(self.app_dir, ROOT_HORIZON)
|
||||||
self.dash_dir = sh.joinpths(self.appdir, ROOT_DASH)
|
self.dash_dir = sh.joinpths(self.app_dir, ROOT_DASH)
|
||||||
self.log_dir = sh.joinpths(self.component_root, LOGS_DIR)
|
self.log_dir = sh.joinpths(self.component_dir, LOGS_DIR)
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
places = list()
|
places = list()
|
||||||
@ -89,16 +76,17 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
|||||||
return places
|
return places
|
||||||
|
|
||||||
def verify(self):
|
def verify(self):
|
||||||
|
comp.PythonInstallComponent.verify(self)
|
||||||
self._check_ug()
|
self._check_ug()
|
||||||
|
|
||||||
def _get_symlinks(self):
|
def _get_symlinks(self):
|
||||||
links = comp.PythonInstallComponent._get_symlinks(self)
|
links = comp.PythonInstallComponent._get_symlinks(self)
|
||||||
src = self._get_target_config_name(HORIZON_APACHE_CONF)
|
src = self._get_target_config_name(HORIZON_APACHE_CONF)
|
||||||
links[src] = self.distro.commands['apache']['settings']['conf-link-target']
|
links[src] = self.distro.get_command('apache', 'settings', 'conf-link-target')
|
||||||
if utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False):
|
if utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False):
|
||||||
#TODO remove this junk, blah, puke that we have to do this
|
# TODO remove this junk, blah, puke that we have to do this
|
||||||
qc = self.instances[settings.QUANTUM_CLIENT]
|
qc = self.instances[settings.QUANTUM_CLIENT]
|
||||||
src_pth = sh.joinpths(qc.appdir, 'quantum')
|
src_pth = sh.joinpths(qc.app_dir, 'quantum')
|
||||||
tgt_dir = sh.joinpths(self.dash_dir, 'quantum')
|
tgt_dir = sh.joinpths(self.dash_dir, 'quantum')
|
||||||
links[src_pth] = tgt_dir
|
links[src_pth] = tgt_dir
|
||||||
return links
|
return links
|
||||||
@ -125,17 +113,18 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
|||||||
return list(CONFIGS)
|
return list(CONFIGS)
|
||||||
|
|
||||||
def _setup_blackhole(self):
|
def _setup_blackhole(self):
|
||||||
#create an empty directory that apache uses as docroot
|
# Create an empty directory that apache uses as docroot
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.appdir, BLACKHOLE_DIR)))
|
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.app_dir, BLACKHOLE_DIR)))
|
||||||
|
|
||||||
def _sync_db(self):
|
def _sync_db(self):
|
||||||
#Initialize the horizon database (it stores sessions and notices shown to users).
|
# Initialize the horizon database (it stores sessions and notices shown to users).
|
||||||
#The user system is external (keystone).
|
# The user system is external (keystone).
|
||||||
LOG.info("Initializing the horizon database.")
|
LOG.info("Initializing the horizon database.")
|
||||||
sh.execute(*DB_SYNC_CMD, cwd=self.appdir)
|
sh.execute(*DB_SYNC_CMD, cwd=self.app_dir)
|
||||||
|
|
||||||
def _ensure_db_access(self):
|
def _ensure_db_access(self):
|
||||||
# ../openstack-dashboard/local needs to be writeable by the runtime user
|
# Need db access:
|
||||||
|
# openstack-dashboard/local needs to be writeable by the runtime user
|
||||||
# since currently its storing the sql-lite databases there (TODO fix that)
|
# since currently its storing the sql-lite databases there (TODO fix that)
|
||||||
path = sh.joinpths(self.dash_dir, 'local')
|
path = sh.joinpths(self.dash_dir, 'local')
|
||||||
if sh.isdir(path):
|
if sh.isdir(path):
|
||||||
@ -151,44 +140,10 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
|||||||
self.tracewriter.dirs_made(*sh.mkdirslist(self.log_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(self.log_dir))
|
||||||
|
|
||||||
def _config_fixups(self):
|
def _config_fixups(self):
|
||||||
#currently just handling rhel fixups
|
pass
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
|
||||||
if not (self.distro in APACHE_FIXUPS_DISTROS):
|
|
||||||
return
|
|
||||||
#it seems like to get this to work
|
|
||||||
#we need to do some conf.d/conf work which sort of sucks
|
|
||||||
(user, group) = self._get_apache_user_group()
|
|
||||||
socket_fn = APACHE_FIXUPS.get("SOCKET_CONF")
|
|
||||||
self.tracewriter.file_touched(socket_fn)
|
|
||||||
#not recorded since we aren't really creating this
|
|
||||||
httpd_fn = APACHE_FIXUPS.get("HTTPD_CONF")
|
|
||||||
with sh.Rooted(True):
|
|
||||||
#fix the socket prefix to someplace we can use
|
|
||||||
fc = "WSGISocketPrefix %s" % (sh.joinpths(self.log_dir, "wsgi-socket"))
|
|
||||||
sh.write_file(socket_fn, fc)
|
|
||||||
#now adjust the run user and group (of httpd.conf)
|
|
||||||
new_lines = list()
|
|
||||||
for line in sh.load_file(httpd_fn).splitlines():
|
|
||||||
if line.startswith("User "):
|
|
||||||
line = "User %s" % (user)
|
|
||||||
if line.startswith("Group "):
|
|
||||||
line = "Group %s" % (group)
|
|
||||||
new_lines.append(line)
|
|
||||||
sh.write_file(httpd_fn, utils.joinlinesep(*new_lines))
|
|
||||||
|
|
||||||
def _fix_quantum(self):
|
|
||||||
if not (utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False)):
|
|
||||||
#make the fake quantum (apparently needed so imports don't fail???)
|
|
||||||
#TODO remove this...
|
|
||||||
quantum_dir = sh.joinpths(self.dash_dir, 'quantum')
|
|
||||||
if not sh.isdir(quantum_dir):
|
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(quantum_dir))
|
|
||||||
for fn in FAKE_QUANTUM_FILES:
|
|
||||||
self.tracewriter.file_touched(sh.touch_file(sh.joinpths(quantum_dir, fn)))
|
|
||||||
|
|
||||||
def post_install(self):
|
def post_install(self):
|
||||||
comp.PythonInstallComponent.post_install(self)
|
comp.PythonInstallComponent.post_install(self)
|
||||||
self._fix_quantum()
|
|
||||||
self._sync_db()
|
self._sync_db()
|
||||||
self._setup_blackhole()
|
self._setup_blackhole()
|
||||||
self._ensure_db_access()
|
self._ensure_db_access()
|
||||||
@ -200,18 +155,18 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
|||||||
return (user, group)
|
return (user, group)
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
#this dict will be used to fill in the configuration
|
# This dict will be used to fill in the configuration
|
||||||
#params with actual values
|
# params with actual values
|
||||||
mp = dict()
|
mp = dict()
|
||||||
if config_fn == HORIZON_APACHE_CONF:
|
if config_fn == HORIZON_APACHE_CONF:
|
||||||
(user, group) = self._get_apache_user_group()
|
(user, group) = self._get_apache_user_group()
|
||||||
|
mp['GROUP'] = group
|
||||||
|
mp['USER'] = user
|
||||||
mp['ACCESS_LOG'] = sh.joinpths(self.log_dir, APACHE_ACCESS_LOG_FN)
|
mp['ACCESS_LOG'] = sh.joinpths(self.log_dir, APACHE_ACCESS_LOG_FN)
|
||||||
mp['ERROR_LOG'] = sh.joinpths(self.log_dir, APACHE_ERROR_LOG_FN)
|
mp['ERROR_LOG'] = sh.joinpths(self.log_dir, APACHE_ERROR_LOG_FN)
|
||||||
mp['GROUP'] = group
|
mp['HORIZON_DIR'] = self.app_dir
|
||||||
mp['HORIZON_DIR'] = self.appdir
|
|
||||||
mp['HORIZON_PORT'] = self.cfg.getdefaulted('horizon', 'port', APACHE_DEF_PORT)
|
mp['HORIZON_PORT'] = self.cfg.getdefaulted('horizon', 'port', APACHE_DEF_PORT)
|
||||||
mp['USER'] = user
|
mp['VPN_DIR'] = sh.joinpths(self.app_dir, "vpn")
|
||||||
mp['VPN_DIR'] = sh.joinpths(self.appdir, "vpn")
|
|
||||||
else:
|
else:
|
||||||
mp['OPENSTACK_HOST'] = self.cfg.get('host', 'ip')
|
mp['OPENSTACK_HOST'] = self.cfg.get('host', 'ip')
|
||||||
return mp
|
return mp
|
||||||
@ -227,7 +182,7 @@ class HorizonRuntime(comp.EmptyRuntime):
|
|||||||
return self.restart()
|
return self.restart()
|
||||||
else:
|
else:
|
||||||
cmds = [{
|
cmds = [{
|
||||||
'cmd': self.distro.commands['apache']['start'],
|
'cmd': self.distro.get_command('apache', 'start'),
|
||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
}]
|
}]
|
||||||
utils.execute_template(*cmds,
|
utils.execute_template(*cmds,
|
||||||
@ -237,7 +192,7 @@ class HorizonRuntime(comp.EmptyRuntime):
|
|||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
cmds = [{
|
cmds = [{
|
||||||
'cmd': self.distro.commands['apache']['restart'],
|
'cmd': self.distro.get_command('apache', 'restart'),
|
||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
}]
|
}]
|
||||||
utils.execute_template(*cmds,
|
utils.execute_template(*cmds,
|
||||||
@ -249,7 +204,7 @@ class HorizonRuntime(comp.EmptyRuntime):
|
|||||||
curr_status = self.status()
|
curr_status = self.status()
|
||||||
if curr_status != comp.STATUS_STOPPED:
|
if curr_status != comp.STATUS_STOPPED:
|
||||||
cmds = [{
|
cmds = [{
|
||||||
'cmd': self.distro.commands['apache']['stop'],
|
'cmd': self.distro.get_command('apache', 'stop'),
|
||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
}]
|
}]
|
||||||
utils.execute_template(*cmds,
|
utils.execute_template(*cmds,
|
||||||
@ -260,7 +215,7 @@ class HorizonRuntime(comp.EmptyRuntime):
|
|||||||
|
|
||||||
def status(self):
|
def status(self):
|
||||||
cmds = [{
|
cmds = [{
|
||||||
'cmd': self.distro.commands['apache']['status'],
|
'cmd': self.distro.get_command('apache', 'status'),
|
||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
}]
|
}]
|
||||||
run_result = utils.execute_template(*cmds,
|
run_result = utils.execute_template(*cmds,
|
||||||
|
@ -27,36 +27,34 @@ from devstack import utils
|
|||||||
|
|
||||||
from devstack.components import db
|
from devstack.components import db
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.KEYSTONE
|
|
||||||
LOG = logging.getLogger("devstack.components.keystone")
|
LOG = logging.getLogger("devstack.components.keystone")
|
||||||
|
|
||||||
#this db will be dropped then created
|
# This db will be dropped then created
|
||||||
DB_NAME = "keystone"
|
DB_NAME = "keystone"
|
||||||
|
|
||||||
#subdirs of the git checkout
|
# Subdirs of the git checkout
|
||||||
BIN_DIR = "bin"
|
BIN_DIR = "bin"
|
||||||
CONFIG_DIR = "etc"
|
CONFIG_DIR = "etc"
|
||||||
|
|
||||||
#simple confs
|
# Simple confs
|
||||||
ROOT_CONF = "keystone.conf"
|
ROOT_CONF = "keystone.conf"
|
||||||
CATALOG_CONF = 'default_catalog.templates'
|
CATALOG_CONF = 'default_catalog.templates'
|
||||||
LOGGING_CONF = "logging.conf"
|
LOGGING_CONF = "logging.conf"
|
||||||
LOGGING_SOURCE_FN = 'logging.conf.sample'
|
LOGGING_SOURCE_FN = 'logging.conf.sample'
|
||||||
CONFIGS = [ROOT_CONF, CATALOG_CONF, LOGGING_CONF]
|
CONFIGS = [ROOT_CONF, CATALOG_CONF, LOGGING_CONF]
|
||||||
|
|
||||||
#this is a special conf
|
# This is a special conf/init script
|
||||||
MANAGE_DATA_CONF = 'keystone_init.sh'
|
MANAGE_DATA_CONF = 'keystone_init.sh'
|
||||||
MANAGE_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
MANAGE_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
||||||
MANAGE_ADMIN_USER = 'admin'
|
MANAGE_ADMIN_USER = 'admin'
|
||||||
MANAGE_DEMO_USER = 'demo'
|
MANAGE_DEMO_USER = 'demo'
|
||||||
MANAGE_INVIS_USER = 'invisible_to_admin'
|
MANAGE_INVIS_USER = 'invisible_to_admin'
|
||||||
|
|
||||||
#sync db command
|
# Sync db command
|
||||||
MANAGE_APP_NAME = 'keystone-manage'
|
MANAGE_APP_NAME = 'keystone-manage'
|
||||||
SYNC_DB_CMD = [sh.joinpths('%BINDIR%', MANAGE_APP_NAME), 'db_sync']
|
SYNC_DB_CMD = [sh.joinpths('%BINDIR%', MANAGE_APP_NAME), 'db_sync']
|
||||||
|
|
||||||
#what to start
|
# What to start
|
||||||
APP_NAME = 'keystone-all'
|
APP_NAME = 'keystone-all'
|
||||||
APP_OPTIONS = {
|
APP_OPTIONS = {
|
||||||
APP_NAME: ['--config-file', sh.joinpths('%ROOT%', CONFIG_DIR, ROOT_CONF),
|
APP_NAME: ['--config-file', sh.joinpths('%ROOT%', CONFIG_DIR, ROOT_CONF),
|
||||||
@ -65,17 +63,19 @@ APP_OPTIONS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#used to wait until started before we can run the data setup script
|
# Used to wait until started before we can run the data setup script
|
||||||
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#swift template additions
|
# Swift template additions
|
||||||
|
# TODO: get rid of these
|
||||||
SWIFT_TEMPL_ADDS = ['catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
SWIFT_TEMPL_ADDS = ['catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
||||||
'catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
'catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
||||||
'catalog.RegionOne.object_store.adminURL = http://%SERVICE_HOST%:8080/',
|
'catalog.RegionOne.object_store.adminURL = http://%SERVICE_HOST%:8080/',
|
||||||
'catalog.RegionOne.object_store.internalURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
'catalog.RegionOne.object_store.internalURL = http://%SERVICE_HOST%:8080/v1/AUTH_$(tenant_id)s',
|
||||||
"catalog.RegionOne.object_store.name = 'Swift Service'"]
|
"catalog.RegionOne.object_store.name = 'Swift Service'"]
|
||||||
|
|
||||||
#quantum template additions
|
# Quantum template additions
|
||||||
|
# TODO: get rid of these
|
||||||
QUANTUM_TEMPL_ADDS = ['catalog.RegionOne.network.publicURL = http://%SERVICE_HOST%:9696/',
|
QUANTUM_TEMPL_ADDS = ['catalog.RegionOne.network.publicURL = http://%SERVICE_HOST%:9696/',
|
||||||
'catalog.RegionOne.network.adminURL = http://%SERVICE_HOST%:9696/',
|
'catalog.RegionOne.network.adminURL = http://%SERVICE_HOST%:9696/',
|
||||||
'catalog.RegionOne.network.internalURL = http://%SERVICE_HOST%:9696/',
|
'catalog.RegionOne.network.internalURL = http://%SERVICE_HOST%:9696/',
|
||||||
@ -85,15 +85,15 @@ QUANTUM_TEMPL_ADDS = ['catalog.RegionOne.network.publicURL = http://%SERVICE_HOS
|
|||||||
class KeystoneUninstaller(comp.PythonUninstallComponent):
|
class KeystoneUninstaller(comp.PythonUninstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
|
|
||||||
|
|
||||||
class KeystoneInstaller(comp.PythonInstallComponent):
|
class KeystoneInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
places = list()
|
places = list()
|
||||||
@ -112,9 +112,9 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
def _sync_db(self):
|
def _sync_db(self):
|
||||||
LOG.info("Syncing keystone to database named %s.", DB_NAME)
|
LOG.info("Syncing keystone to database named %s.", DB_NAME)
|
||||||
params = dict()
|
params = dict()
|
||||||
params['BINDIR'] = self.bindir
|
params['BINDIR'] = self.bin_dir
|
||||||
cmds = [{'cmd': SYNC_DB_CMD}]
|
cmds = [{'cmd': SYNC_DB_CMD}]
|
||||||
utils.execute_template(*cmds, cwd=self.bindir, params=params)
|
utils.execute_template(*cmds, cwd=self.bin_dir, params=params)
|
||||||
|
|
||||||
def _get_config_files(self):
|
def _get_config_files(self):
|
||||||
return list(CONFIGS)
|
return list(CONFIGS)
|
||||||
@ -129,16 +129,16 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
(_, contents) = utils.load_template(self.component_name, MANAGE_DATA_CONF)
|
(_, contents) = utils.load_template(self.component_name, MANAGE_DATA_CONF)
|
||||||
params = self._get_param_map(MANAGE_DATA_CONF)
|
params = self._get_param_map(MANAGE_DATA_CONF)
|
||||||
contents = utils.param_replace(contents, params, True)
|
contents = utils.param_replace(contents, params, True)
|
||||||
tgt_fn = sh.joinpths(self.bindir, MANAGE_DATA_CONF)
|
tgt_fn = sh.joinpths(self.bin_dir, MANAGE_DATA_CONF)
|
||||||
sh.write_file(tgt_fn, contents)
|
sh.write_file(tgt_fn, contents)
|
||||||
sh.chmod(tgt_fn, 0755)
|
sh.chmod(tgt_fn, 0755)
|
||||||
self.tracewriter.file_touched(tgt_fn)
|
self.tracewriter.file_touched(tgt_fn)
|
||||||
|
|
||||||
def _config_adjust(self, contents, name):
|
def _config_adjust(self, contents, name):
|
||||||
if name == ROOT_CONF:
|
if name == ROOT_CONF:
|
||||||
#use config parser and
|
# Use config parser and
|
||||||
#then extract known configs that
|
# then extract known configs that
|
||||||
#will need locations/directories/files made (or touched)...
|
# ill need locations/directories/files made (or touched)...
|
||||||
with io.BytesIO(contents) as stream:
|
with io.BytesIO(contents) as stream:
|
||||||
config = cfg.IgnoreMissingConfigParser()
|
config = cfg.IgnoreMissingConfigParser()
|
||||||
config.readfp(stream)
|
config.readfp(stream)
|
||||||
@ -149,7 +149,7 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
if log_dir:
|
if log_dir:
|
||||||
LOG.info("Ensuring log directory %s exists." % (log_dir))
|
LOG.info("Ensuring log directory %s exists." % (log_dir))
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(log_dir))
|
self.tracewriter.dirs_made(*sh.mkdirslist(log_dir))
|
||||||
#destroy then recreate it (the log file)
|
# Destroy then recreate it (the log file)
|
||||||
sh.unlink(log_filename)
|
sh.unlink(log_filename)
|
||||||
self.tracewriter.file_touched(sh.touch_file(log_filename))
|
self.tracewriter.file_touched(sh.touch_file(log_filename))
|
||||||
elif name == CATALOG_CONF:
|
elif name == CATALOG_CONF:
|
||||||
@ -174,7 +174,7 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _get_source_config(self, config_fn):
|
def _get_source_config(self, config_fn):
|
||||||
if config_fn == LOGGING_CONF:
|
if config_fn == LOGGING_CONF:
|
||||||
fn = sh.joinpths(self.cfgdir, LOGGING_SOURCE_FN)
|
fn = sh.joinpths(self.cfg_dir, LOGGING_SOURCE_FN)
|
||||||
contents = sh.load_file(fn)
|
contents = sh.load_file(fn)
|
||||||
return (fn, contents)
|
return (fn, contents)
|
||||||
return comp.PythonInstallComponent._get_source_config(self, config_fn)
|
return comp.PythonInstallComponent._get_source_config(self, config_fn)
|
||||||
@ -183,16 +183,16 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
get_shared_params(self.cfg, self.pw_gen)
|
get_shared_params(self.cfg, self.pw_gen)
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
#these be used to fill in the configuration/cmds +
|
# These be used to fill in the configuration/cmds +
|
||||||
#params with actual values
|
# params with actual values
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
|
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
|
||||||
mp['DEST'] = self.appdir
|
mp['DEST'] = self.app_dir
|
||||||
mp['BIN_DIR'] = self.bindir
|
mp['BIN_DIR'] = self.bin_dir
|
||||||
mp['CONFIG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF)
|
mp['CONFIG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF)
|
||||||
if config_fn == ROOT_CONF:
|
if config_fn == ROOT_CONF:
|
||||||
mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
||||||
mp['KEYSTONE_DIR'] = self.appdir
|
mp['KEYSTONE_DIR'] = self.app_dir
|
||||||
mp.update(get_shared_params(self.cfg, self.pw_gen))
|
mp.update(get_shared_params(self.cfg, self.pw_gen))
|
||||||
elif config_fn == MANAGE_DATA_CONF:
|
elif config_fn == MANAGE_DATA_CONF:
|
||||||
mp.update(get_shared_params(self.cfg, self.pw_gen))
|
mp.update(get_shared_params(self.cfg, self.pw_gen))
|
||||||
@ -202,20 +202,20 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
|||||||
class KeystoneRuntime(comp.PythonRuntime):
|
class KeystoneRuntime(comp.PythonRuntime):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonRuntime.__init__(self, *args, **kargs)
|
comp.PythonRuntime.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
|
|
||||||
def post_start(self):
|
def post_start(self):
|
||||||
tgt_fn = sh.joinpths(self.bindir, MANAGE_DATA_CONF)
|
tgt_fn = sh.joinpths(self.bin_dir, MANAGE_DATA_CONF)
|
||||||
if sh.isfile(tgt_fn):
|
if sh.isfile(tgt_fn):
|
||||||
#still there, run it
|
# If its still there, run it
|
||||||
#these environment additions are important
|
# these environment additions are important
|
||||||
#in that they eventually affect how this script runs
|
# in that they eventually affect how this script runs
|
||||||
LOG.info("Waiting %s seconds so that keystone can start up before running first time init." % (WAIT_ONLINE_TO))
|
LOG.info("Waiting %s seconds so that keystone can start up before running first time init." % (WAIT_ONLINE_TO))
|
||||||
sh.sleep(WAIT_ONLINE_TO)
|
sh.sleep(WAIT_ONLINE_TO)
|
||||||
env = dict()
|
env = dict()
|
||||||
env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
|
env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
|
||||||
env['BIN_DIR'] = self.bindir
|
env['BIN_DIR'] = self.bin_dir
|
||||||
setup_cmd = MANAGE_CMD_ROOT + [tgt_fn]
|
setup_cmd = MANAGE_CMD_ROOT + [tgt_fn]
|
||||||
LOG.info("Running (%s) command to initialize keystone." % (" ".join(setup_cmd)))
|
LOG.info("Running (%s) command to initialize keystone." % (" ".join(setup_cmd)))
|
||||||
sh.execute(*setup_cmd, env_overrides=env, run_as_root=False)
|
sh.execute(*setup_cmd, env_overrides=env, run_as_root=False)
|
||||||
@ -227,7 +227,7 @@ class KeystoneRuntime(comp.PythonRuntime):
|
|||||||
for app_name in APP_OPTIONS.keys():
|
for app_name in APP_OPTIONS.keys():
|
||||||
apps.append({
|
apps.append({
|
||||||
'name': app_name,
|
'name': app_name,
|
||||||
'path': sh.joinpths(self.bindir, app_name),
|
'path': sh.joinpths(self.bin_dir, app_name),
|
||||||
})
|
})
|
||||||
return apps
|
return apps
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ def get_shared_params(config, pw_gen, service_user_name=None):
|
|||||||
mp = dict()
|
mp = dict()
|
||||||
host_ip = config.get('host', 'ip')
|
host_ip = config.get('host', 'ip')
|
||||||
|
|
||||||
#these match what is in keystone_init.sh
|
# These match what is in keystone_init.sh
|
||||||
mp['SERVICE_TENANT_NAME'] = 'service'
|
mp['SERVICE_TENANT_NAME'] = 'service'
|
||||||
if service_user_name:
|
if service_user_name:
|
||||||
mp['SERVICE_USERNAME'] = str(service_user_name)
|
mp['SERVICE_USERNAME'] = str(service_user_name)
|
||||||
@ -248,7 +248,7 @@ def get_shared_params(config, pw_gen, service_user_name=None):
|
|||||||
mp['ADMIN_TENANT_NAME'] = mp['ADMIN_USER_NAME']
|
mp['ADMIN_TENANT_NAME'] = mp['ADMIN_USER_NAME']
|
||||||
mp['DEMO_TENANT_NAME'] = mp['DEMO_USER_NAME']
|
mp['DEMO_TENANT_NAME'] = mp['DEMO_USER_NAME']
|
||||||
|
|
||||||
#tokens and passwords
|
# Tokens and passwords
|
||||||
mp['SERVICE_TOKEN'] = pw_gen.get_password(
|
mp['SERVICE_TOKEN'] = pw_gen.get_password(
|
||||||
"service_token",
|
"service_token",
|
||||||
'the service admin token',
|
'the service admin token',
|
||||||
@ -263,7 +263,7 @@ def get_shared_params(config, pw_gen, service_user_name=None):
|
|||||||
'service authentication',
|
'service authentication',
|
||||||
)
|
)
|
||||||
|
|
||||||
#components of the auth endpoint
|
# Components of the auth endpoint
|
||||||
keystone_auth_host = config.getdefaulted('keystone', 'keystone_auth_host', host_ip)
|
keystone_auth_host = config.getdefaulted('keystone', 'keystone_auth_host', host_ip)
|
||||||
mp['KEYSTONE_AUTH_HOST'] = keystone_auth_host
|
mp['KEYSTONE_AUTH_HOST'] = keystone_auth_host
|
||||||
keystone_auth_port = config.getdefaulted('keystone', 'keystone_auth_port', '35357')
|
keystone_auth_port = config.getdefaulted('keystone', 'keystone_auth_port', '35357')
|
||||||
@ -271,7 +271,7 @@ def get_shared_params(config, pw_gen, service_user_name=None):
|
|||||||
keystone_auth_proto = config.getdefaulted('keystone', 'keystone_auth_protocol', 'http')
|
keystone_auth_proto = config.getdefaulted('keystone', 'keystone_auth_protocol', 'http')
|
||||||
mp['KEYSTONE_AUTH_PROTOCOL'] = keystone_auth_proto
|
mp['KEYSTONE_AUTH_PROTOCOL'] = keystone_auth_proto
|
||||||
|
|
||||||
#components of the service endpoint
|
# Components of the service endpoint
|
||||||
keystone_service_host = config.getdefaulted('keystone', 'keystone_service_host', host_ip)
|
keystone_service_host = config.getdefaulted('keystone', 'keystone_service_host', host_ip)
|
||||||
mp['KEYSTONE_SERVICE_HOST'] = keystone_service_host
|
mp['KEYSTONE_SERVICE_HOST'] = keystone_service_host
|
||||||
keystone_service_port = config.getdefaulted('keystone', 'keystone_service_port', '5000')
|
keystone_service_port = config.getdefaulted('keystone', 'keystone_service_port', '5000')
|
||||||
@ -279,7 +279,7 @@ def get_shared_params(config, pw_gen, service_user_name=None):
|
|||||||
keystone_service_proto = config.getdefaulted('keystone', 'keystone_service_protocol', 'http')
|
keystone_service_proto = config.getdefaulted('keystone', 'keystone_service_protocol', 'http')
|
||||||
mp['KEYSTONE_SERVICE_PROTOCOL'] = keystone_service_proto
|
mp['KEYSTONE_SERVICE_PROTOCOL'] = keystone_service_proto
|
||||||
|
|
||||||
#http/https endpoints
|
# Uri's of the http/https endpoints
|
||||||
mp['AUTH_ENDPOINT'] = urlunparse((keystone_auth_proto,
|
mp['AUTH_ENDPOINT'] = urlunparse((keystone_auth_proto,
|
||||||
"%s:%s" % (keystone_auth_host, keystone_auth_port),
|
"%s:%s" % (keystone_auth_host, keystone_auth_port),
|
||||||
"v2.0", "", "", ""))
|
"v2.0", "", "", ""))
|
||||||
|
@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
from devstack import component as comp
|
from devstack import component as comp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.KEYSTONE_CLIENT
|
|
||||||
LOG = logging.getLogger("devstack.components.keystone_client")
|
LOG = logging.getLogger("devstack.components.keystone_client")
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,41 +25,39 @@ from devstack import utils
|
|||||||
|
|
||||||
from devstack.components import db
|
from devstack.components import db
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.MELANGE
|
|
||||||
LOG = logging.getLogger("devstack.components.melange")
|
LOG = logging.getLogger("devstack.components.melange")
|
||||||
|
|
||||||
#this db will be dropped then created
|
# This db will be dropped then created
|
||||||
DB_NAME = 'melange'
|
DB_NAME = 'melange'
|
||||||
|
|
||||||
#subdirs of the checkout/download
|
# Subdirs of the checkout/download
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
|
|
||||||
#configs
|
# Basic configs
|
||||||
ROOT_CONF = 'melange.conf.sample'
|
ROOT_CONF = 'melange.conf.sample'
|
||||||
ROOT_CONF_REAL_NAME = 'melange.conf'
|
ROOT_CONF_REAL_NAME = 'melange.conf'
|
||||||
CONFIGS = [ROOT_CONF]
|
CONFIGS = [ROOT_CONF]
|
||||||
CFG_LOC = ['etc', 'melange']
|
CFG_LOC = ['etc', 'melange']
|
||||||
|
|
||||||
#sensible defaults
|
# Sensible defaults
|
||||||
DEF_CIDR_RANGE = 'FE-EE-DD-00-00-00/24'
|
DEF_CIDR_RANGE = 'FE-EE-DD-00-00-00/24'
|
||||||
|
|
||||||
#how we sync melange with the db
|
# How we sync melange with the db
|
||||||
DB_SYNC_CMD = [
|
DB_SYNC_CMD = [
|
||||||
{'cmd': ['%BINDIR%/melange-manage', '--config-file=%CFG_FILE%', 'db_sync']},
|
{'cmd': ['%BIN_DIR%/melange-manage', '--config-file=%CFG_FILE%', 'db_sync']},
|
||||||
]
|
]
|
||||||
|
|
||||||
#???
|
# TODO: ???
|
||||||
CIDR_CREATE_CMD = [
|
CIDR_CREATE_CMD = [
|
||||||
{'cmd': ['melange', 'mac_address_range', 'create', 'cidr', '%CIDR_RANGE%']},
|
{'cmd': ['melange', 'mac_address_range', 'create', 'cidr', '%CIDR_RANGE%']},
|
||||||
]
|
]
|
||||||
|
|
||||||
#what to start
|
# What to start
|
||||||
APP_OPTIONS = {
|
APP_OPTIONS = {
|
||||||
'melange-server': ['--config-file', '%CFG_FILE%'],
|
'melange-server': ['--config-file', '%CFG_FILE%'],
|
||||||
}
|
}
|
||||||
|
|
||||||
#subcomponent that specifies we should make the network cidr using melange
|
# Special option that specifies we should make the network cidr using melange
|
||||||
CREATE_CIDR = "create-cidr"
|
CREATE_CIDR = "create-cidr"
|
||||||
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
@ -72,8 +70,8 @@ class MelangeUninstaller(comp.PythonUninstallComponent):
|
|||||||
class MelangeInstaller(comp.PythonInstallComponent):
|
class MelangeInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, *CFG_LOC)
|
self.cfg_dir = sh.joinpths(self.app_dir, *CFG_LOC)
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
places = list()
|
places = list()
|
||||||
@ -96,8 +94,8 @@ class MelangeInstaller(comp.PythonInstallComponent):
|
|||||||
def _sync_db(self):
|
def _sync_db(self):
|
||||||
LOG.info("Syncing the database with melange.")
|
LOG.info("Syncing the database with melange.")
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['BINDIR'] = self.bindir
|
mp['BIN_DIR'] = self.bin_dir
|
||||||
mp['CFG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME)
|
mp['CFG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
|
||||||
utils.execute_template(*DB_SYNC_CMD, params=mp)
|
utils.execute_template(*DB_SYNC_CMD, params=mp)
|
||||||
|
|
||||||
def _get_config_files(self):
|
def _get_config_files(self):
|
||||||
@ -122,7 +120,7 @@ class MelangeInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _get_source_config(self, config_fn):
|
def _get_source_config(self, config_fn):
|
||||||
if config_fn == ROOT_CONF:
|
if config_fn == ROOT_CONF:
|
||||||
srcfn = sh.joinpths(self.cfgdir, config_fn)
|
srcfn = sh.joinpths(self.cfg_dir, config_fn)
|
||||||
contents = sh.load_file(srcfn)
|
contents = sh.load_file(srcfn)
|
||||||
return (srcfn, contents)
|
return (srcfn, contents)
|
||||||
else:
|
else:
|
||||||
@ -130,7 +128,7 @@ class MelangeInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _get_target_config_name(self, config_fn):
|
def _get_target_config_name(self, config_fn):
|
||||||
if config_fn == ROOT_CONF:
|
if config_fn == ROOT_CONF:
|
||||||
return sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME)
|
return sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
|
||||||
else:
|
else:
|
||||||
return comp.PythonInstallComponent._get_target_config_name(self, config_fn)
|
return comp.PythonInstallComponent._get_target_config_name(self, config_fn)
|
||||||
|
|
||||||
@ -138,15 +136,15 @@ class MelangeInstaller(comp.PythonInstallComponent):
|
|||||||
class MelangeRuntime(comp.PythonRuntime):
|
class MelangeRuntime(comp.PythonRuntime):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonRuntime.__init__(self, *args, **kargs)
|
comp.PythonRuntime.__init__(self, *args, **kargs)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, *CFG_LOC)
|
self.cfg_dir = sh.joinpths(self.app_dir, *CFG_LOC)
|
||||||
|
|
||||||
def _get_apps_to_start(self):
|
def _get_apps_to_start(self):
|
||||||
apps = list()
|
apps = list()
|
||||||
for app_name in APP_OPTIONS.keys():
|
for app_name in APP_OPTIONS.keys():
|
||||||
apps.append({
|
apps.append({
|
||||||
'name': app_name,
|
'name': app_name,
|
||||||
'path': sh.joinpths(self.bindir, app_name),
|
'path': sh.joinpths(self.bin_dir, app_name),
|
||||||
})
|
})
|
||||||
return apps
|
return apps
|
||||||
|
|
||||||
@ -155,14 +153,14 @@ class MelangeRuntime(comp.PythonRuntime):
|
|||||||
|
|
||||||
def _get_param_map(self, app_name):
|
def _get_param_map(self, app_name):
|
||||||
pmap = comp.PythonRuntime._get_param_map(self, app_name)
|
pmap = comp.PythonRuntime._get_param_map(self, app_name)
|
||||||
pmap['CFG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME)
|
pmap['CFG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
|
||||||
return pmap
|
return pmap
|
||||||
|
|
||||||
def post_start(self):
|
def post_start(self):
|
||||||
comp.PythonRuntime.post_start(self)
|
comp.PythonRuntime.post_start(self)
|
||||||
# FIXME: This is a bit of a hack. How do we document "flags" like this?
|
# FIXME: This is a bit of a hack. How do we document "flags" like this?
|
||||||
flags = self.component_opts.get('flags', [])
|
flags = []
|
||||||
if CREATE_CIDR in flags or not flags:
|
if CREATE_CIDR in flags:
|
||||||
LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO))
|
LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO))
|
||||||
sh.sleep(WAIT_ONLINE_TO)
|
sh.sleep(WAIT_ONLINE_TO)
|
||||||
mp = dict()
|
mp = dict()
|
||||||
|
@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
from devstack import component as comp
|
from devstack import component as comp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.MELANGE_CLIENT
|
|
||||||
LOG = logging.getLogger("devstack.components.melange_client")
|
LOG = logging.getLogger("devstack.components.melange_client")
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,17 +28,15 @@ from devstack import utils
|
|||||||
from devstack.components import db
|
from devstack.components import db
|
||||||
from devstack.components import keystone
|
from devstack.components import keystone
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.NOVA
|
|
||||||
LOG = logging.getLogger('devstack.components.nova')
|
LOG = logging.getLogger('devstack.components.nova')
|
||||||
|
|
||||||
#special generated conf
|
# Special generated conf
|
||||||
API_CONF = 'nova.conf'
|
API_CONF = 'nova.conf'
|
||||||
|
|
||||||
#how we reference some config files (in applications)
|
# How we reference some config files (in applications)
|
||||||
CFG_FILE_OPT = '--config-file'
|
CFG_FILE_OPT = '--config-file'
|
||||||
|
|
||||||
#normal conf
|
# Normal conf
|
||||||
PASTE_CONF = 'nova-api-paste.ini'
|
PASTE_CONF = 'nova-api-paste.ini'
|
||||||
PASTE_SOURCE_FN = 'api-paste.ini'
|
PASTE_SOURCE_FN = 'api-paste.ini'
|
||||||
POLICY_CONF = 'policy.json'
|
POLICY_CONF = 'policy.json'
|
||||||
@ -47,19 +45,19 @@ LOGGING_CONF = "logging.conf"
|
|||||||
CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF]
|
CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF]
|
||||||
ADJUST_CONFIGS = [PASTE_CONF]
|
ADJUST_CONFIGS = [PASTE_CONF]
|
||||||
|
|
||||||
#this is a special conf
|
# This is a special conf
|
||||||
NET_INIT_CONF = 'nova-network-init.sh'
|
NET_INIT_CONF = 'nova-network-init.sh'
|
||||||
NET_INIT_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
NET_INIT_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
||||||
|
|
||||||
#this db will be dropped then created
|
# This db will be dropped then created
|
||||||
DB_NAME = 'nova'
|
DB_NAME = 'nova'
|
||||||
|
|
||||||
#this makes the database be in sync with nova
|
# This makes the database be in sync with nova
|
||||||
DB_SYNC_CMD = [
|
DB_SYNC_CMD = [
|
||||||
{'cmd': ['%BINDIR%/nova-manage', CFG_FILE_OPT, '%CFGFILE%', 'db', 'sync']},
|
{'cmd': ['%BIN_DIR%/nova-manage', CFG_FILE_OPT, '%CFGFILE%', 'db', 'sync']},
|
||||||
]
|
]
|
||||||
|
|
||||||
#these are used for nova volumens
|
# These are used for nova volumes
|
||||||
VG_CHECK_CMD = [
|
VG_CHECK_CMD = [
|
||||||
{'cmd': ['vgs', '%VOLUME_GROUP%'],
|
{'cmd': ['vgs', '%VOLUME_GROUP%'],
|
||||||
'run_as_root': True}
|
'run_as_root': True}
|
||||||
@ -81,23 +79,8 @@ VG_LVREMOVE_CMD = [
|
|||||||
'run_as_root': True}
|
'run_as_root': True}
|
||||||
]
|
]
|
||||||
|
|
||||||
# iscsi restart commands
|
|
||||||
RESTART_TGT_CMD = {
|
|
||||||
settings.UBUNTU11: [
|
|
||||||
{'cmd': ['stop', 'tgt'], 'run_as_root': True},
|
|
||||||
{'cmd': ['start', 'tgt'], 'run_as_root': True}
|
|
||||||
],
|
|
||||||
settings.RHEL6: [
|
|
||||||
{'cmd': ['service', 'tgtd', 'stop'], 'run_as_root': True},
|
|
||||||
{'cmd': ['service', 'tgtd', 'start'], 'run_as_root': True}
|
|
||||||
],
|
|
||||||
settings.FEDORA16: [
|
|
||||||
{'cmd': ['service', 'tgtd', 'stop'], 'run_as_root': True},
|
|
||||||
{'cmd': ['service', 'tgtd', 'start'], 'run_as_root': True}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
# NCPU, NVOL, NAPI ... are here as possible subcomponents of nova
|
# NCPU, NVOL, NAPI ... are here as possible subsystems of nova
|
||||||
NCPU = "cpu"
|
NCPU = "cpu"
|
||||||
NVOL = "vol"
|
NVOL = "vol"
|
||||||
NAPI = "api"
|
NAPI = "api"
|
||||||
@ -107,7 +90,7 @@ NCERT = "cert"
|
|||||||
NSCHED = "sched"
|
NSCHED = "sched"
|
||||||
NCAUTH = "cauth"
|
NCAUTH = "cauth"
|
||||||
NXVNC = "xvnc"
|
NXVNC = "xvnc"
|
||||||
SUBCOMPONENTS = [NCPU, NVOL, NAPI,
|
SUBSYSTEMS = [NCPU, NVOL, NAPI,
|
||||||
NOBJ, NNET, NCERT, NSCHED, NCAUTH, NXVNC]
|
NOBJ, NNET, NCERT, NSCHED, NCAUTH, NXVNC]
|
||||||
|
|
||||||
# What to start
|
# What to start
|
||||||
@ -137,17 +120,17 @@ SUB_COMPONENT_NAME_MAP = {
|
|||||||
NXVNC: 'nova-xvpvncproxy',
|
NXVNC: 'nova-xvpvncproxy',
|
||||||
}
|
}
|
||||||
|
|
||||||
#subdirs of the checkout/download
|
# Subdirs of the checkout/download
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
CONFIG_DIR = "etc"
|
CONFIG_DIR = "etc"
|
||||||
|
|
||||||
#network class/driver/manager templs
|
# Network class/driver/manager templs
|
||||||
QUANTUM_MANAGER = 'nova.network.quantum.manager.QuantumManager'
|
QUANTUM_MANAGER = 'nova.network.quantum.manager.QuantumManager'
|
||||||
QUANTUM_IPAM_LIB = 'nova.network.quantum.melange_ipam_lib'
|
QUANTUM_IPAM_LIB = 'nova.network.quantum.melange_ipam_lib'
|
||||||
NET_MANAGER_TEMPLATE = 'nova.network.manager.%s'
|
NET_MANAGER_TEMPLATE = 'nova.network.manager.%s'
|
||||||
FIRE_MANAGER_TEMPLATE = 'nova.virt.libvirt.firewall.%s'
|
FIRE_MANAGER_TEMPLATE = 'nova.virt.libvirt.firewall.%s'
|
||||||
|
|
||||||
#sensible defaults
|
# Sensible defaults
|
||||||
DEF_IMAGE_SERVICE = 'nova.image.glance.GlanceImageService'
|
DEF_IMAGE_SERVICE = 'nova.image.glance.GlanceImageService'
|
||||||
DEF_SCHEDULER = 'nova.scheduler.simple.SimpleScheduler'
|
DEF_SCHEDULER = 'nova.scheduler.simple.SimpleScheduler'
|
||||||
DEF_GLANCE_PORT = 9292
|
DEF_GLANCE_PORT = 9292
|
||||||
@ -160,11 +143,11 @@ DEF_NET_MANAGER = 'FlatDHCPManager'
|
|||||||
DEF_VOL_PREFIX = 'volume-'
|
DEF_VOL_PREFIX = 'volume-'
|
||||||
DEF_VOL_TEMPL = DEF_VOL_PREFIX + '%08x'
|
DEF_VOL_TEMPL = DEF_VOL_PREFIX + '%08x'
|
||||||
|
|
||||||
#default virt types
|
# Default virt types
|
||||||
DEF_VIRT_DRIVER = 'libvirt'
|
DEF_VIRT_DRIVER = 'libvirt'
|
||||||
DEF_VIRT_TYPE = 'qemu'
|
DEF_VIRT_TYPE = 'qemu'
|
||||||
|
|
||||||
#virt drivers to there connection name
|
# Virt drivers map -> to there connection name
|
||||||
VIRT_DRIVER_CON_MAP = {
|
VIRT_DRIVER_CON_MAP = {
|
||||||
'libvirt': 'libvirt',
|
'libvirt': 'libvirt',
|
||||||
'xenserver': 'xenapi',
|
'xenserver': 'xenapi',
|
||||||
@ -172,7 +155,7 @@ VIRT_DRIVER_CON_MAP = {
|
|||||||
'baremetal': 'baremetal',
|
'baremetal': 'baremetal',
|
||||||
}
|
}
|
||||||
|
|
||||||
#only turned on if vswitch enabled
|
# Only turned on if openvswitch enabled
|
||||||
QUANTUM_OPENSWITCH_OPS = {
|
QUANTUM_OPENSWITCH_OPS = {
|
||||||
'libvirt_vif_type': 'ethernet',
|
'libvirt_vif_type': 'ethernet',
|
||||||
'libvirt_vif_driver': 'nova.virt.libvirt.vif.LibvirtOpenVswitchDriver',
|
'libvirt_vif_driver': 'nova.virt.libvirt.vif.LibvirtOpenVswitchDriver',
|
||||||
@ -180,24 +163,24 @@ QUANTUM_OPENSWITCH_OPS = {
|
|||||||
'quantum_use_dhcp': True,
|
'quantum_use_dhcp': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
#this is a special conf
|
# This is a special conf
|
||||||
CLEANER_DATA_CONF = 'nova-clean.sh'
|
CLEANER_DATA_CONF = 'nova-clean.sh'
|
||||||
CLEANER_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
CLEANER_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
||||||
|
|
||||||
|
# FIXME:
|
||||||
#rhel6/fedora libvirt policy
|
#rhel6/fedora libvirt policy
|
||||||
#http://wiki.libvirt.org/page/SSHPolicyKitSetup
|
#http://wiki.libvirt.org/page/SSHPolicyKitSetup
|
||||||
LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla"
|
#LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla"
|
||||||
LIBVIRT_POLICY_CONTENTS = """
|
#LIBVIRT_POLICY_CONTENTS = """
|
||||||
[libvirt Management Access]
|
#[libvirt Management Access]
|
||||||
Identity=unix-group:libvirtd
|
#Identity=unix-group:libvirtd
|
||||||
Action=org.libvirt.unix.manage
|
#Action=org.libvirt.unix.manage
|
||||||
ResultAny=yes
|
#ResultAny=yes
|
||||||
ResultInactive=yes
|
#ResultInactive=yes
|
||||||
ResultActive=yes
|
#ResultActive=yes
|
||||||
"""
|
#"""
|
||||||
POLICY_DISTROS = [settings.RHEL6, settings.FEDORA16]
|
|
||||||
|
|
||||||
#xenserver specific defaults
|
# Xenserver specific defaults
|
||||||
XS_DEF_INTERFACE = 'eth1'
|
XS_DEF_INTERFACE = 'eth1'
|
||||||
XA_CONNECTION_ADDR = '169.254.0.1'
|
XA_CONNECTION_ADDR = '169.254.0.1'
|
||||||
XS_VNC_ADDR = XA_CONNECTION_ADDR
|
XS_VNC_ADDR = XA_CONNECTION_ADDR
|
||||||
@ -206,19 +189,19 @@ XA_CONNECTION_PORT = 80
|
|||||||
XA_DEF_USER = 'root'
|
XA_DEF_USER = 'root'
|
||||||
XA_DEF_CONNECTION_URL = urlunparse(('http', "%s:%s" % (XA_CONNECTION_ADDR, XA_CONNECTION_PORT), "", '', '', ''))
|
XA_DEF_CONNECTION_URL = urlunparse(('http', "%s:%s" % (XA_CONNECTION_ADDR, XA_CONNECTION_PORT), "", '', '', ''))
|
||||||
|
|
||||||
#vnc specific defaults
|
# Vnc specific defaults
|
||||||
VNC_DEF_ADDR = '127.0.0.1'
|
VNC_DEF_ADDR = '127.0.0.1'
|
||||||
|
|
||||||
#std compute extensions
|
# Nova std compute extensions
|
||||||
STD_COMPUTE_EXTS = 'nova.api.openstack.compute.contrib.standard_extensions'
|
STD_COMPUTE_EXTS = 'nova.api.openstack.compute.contrib.standard_extensions'
|
||||||
|
|
||||||
#config keys we warm up so u won't be prompted later
|
# Config keys we warm up so u won't be prompted later
|
||||||
WARMUP_PWS = ['rabbit']
|
WARMUP_PWS = ['rabbit']
|
||||||
|
|
||||||
#used to wait until started before we can run the data setup script
|
# Used to wait until started before we can run the data setup script
|
||||||
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#nova conf default section
|
# Nova conf default section
|
||||||
NV_CONF_DEF_SECTION = "[DEFAULT]"
|
NV_CONF_DEF_SECTION = "[DEFAULT]"
|
||||||
|
|
||||||
|
|
||||||
@ -244,21 +227,24 @@ def _canon_libvirt_type(virt_type):
|
|||||||
class NovaUninstaller(comp.PythonUninstallComponent):
|
class NovaUninstaller(comp.PythonUninstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return SUBSYSTEMS
|
||||||
|
|
||||||
def pre_uninstall(self):
|
def pre_uninstall(self):
|
||||||
self._clear_libvirt_domains()
|
self._clear_libvirt_domains()
|
||||||
self._clean_it()
|
self._clean_it()
|
||||||
|
|
||||||
def _clean_it(self):
|
def _clean_it(self):
|
||||||
#these environment additions are important
|
# These environment additions are important
|
||||||
#in that they eventually affect how this script runs
|
# in that they eventually affect how this script runs
|
||||||
env = dict()
|
env = dict()
|
||||||
env['ENABLED_SERVICES'] = ",".join(SUBCOMPONENTS)
|
env['ENABLED_SERVICES'] = ",".join(self.desired_subsystems)
|
||||||
env['BIN_DIR'] = self.bindir
|
env['BIN_DIR'] = self.bin_dir
|
||||||
env['VOLUME_NAME_PREFIX'] = self.cfg.getdefaulted('nova', 'volume_name_prefix', DEF_VOL_PREFIX)
|
env['VOLUME_NAME_PREFIX'] = self.cfg.getdefaulted('nova', 'volume_name_prefix', DEF_VOL_PREFIX)
|
||||||
cleaner_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF)
|
cleaner_fn = sh.joinpths(self.bin_dir, CLEANER_DATA_CONF)
|
||||||
if sh.isfile(cleaner_fn):
|
if sh.isfile(cleaner_fn):
|
||||||
LOG.info("Cleaning up your system by running nova cleaner script [%s]." % (cleaner_fn))
|
LOG.info("Cleaning up your system by running nova cleaner script [%s]." % (cleaner_fn))
|
||||||
cmd = CLEANER_CMD_ROOT + [cleaner_fn]
|
cmd = CLEANER_CMD_ROOT + [cleaner_fn]
|
||||||
@ -269,28 +255,28 @@ class NovaUninstaller(comp.PythonUninstallComponent):
|
|||||||
if virt_driver == 'libvirt':
|
if virt_driver == 'libvirt':
|
||||||
inst_prefix = self.cfg.getdefaulted('nova', 'instance_name_prefix', DEF_INSTANCE_PREFIX)
|
inst_prefix = self.cfg.getdefaulted('nova', 'instance_name_prefix', DEF_INSTANCE_PREFIX)
|
||||||
libvirt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
|
libvirt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
|
||||||
virsh.clear_libvirt_domains(self.distro.name, libvirt_type, inst_prefix)
|
virsh.clear_libvirt_domains(self.distro, libvirt_type, inst_prefix)
|
||||||
|
|
||||||
|
|
||||||
class NovaInstaller(comp.PythonInstallComponent):
|
class NovaInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.paste_conf_fn = self._get_target_config_name(PASTE_CONF)
|
self.paste_conf_fn = self._get_target_config_name(PASTE_CONF)
|
||||||
self.volumes_enabled = False
|
self.volumes_enabled = False
|
||||||
package_names = [p['name']
|
if NVOL in self.desired_subsystems:
|
||||||
for p in self.component_opts.get('packages', [])
|
|
||||||
]
|
|
||||||
if NVOL in package_names:
|
|
||||||
self.volumes_enabled = True
|
self.volumes_enabled = True
|
||||||
self.xvnc_enabled = False
|
self.xvnc_enabled = False
|
||||||
if NXVNC in package_names:
|
if NXVNC in self.desired_subsystems:
|
||||||
self.xvnc_enabled = True
|
self.xvnc_enabled = True
|
||||||
|
|
||||||
|
def known_subsystems(self):
|
||||||
|
return SUBSYSTEMS
|
||||||
|
|
||||||
def _get_symlinks(self):
|
def _get_symlinks(self):
|
||||||
links = comp.PythonInstallComponent._get_symlinks(self)
|
links = comp.PythonInstallComponent._get_symlinks(self)
|
||||||
source_fn = sh.joinpths(self.cfgdir, API_CONF)
|
source_fn = sh.joinpths(self.cfg_dir, API_CONF)
|
||||||
links[source_fn] = sh.joinpths(self._get_link_dir(), API_CONF)
|
links[source_fn] = sh.joinpths(self._get_link_dir(), API_CONF)
|
||||||
return links
|
return links
|
||||||
|
|
||||||
@ -303,11 +289,12 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
return places
|
return places
|
||||||
|
|
||||||
def warm_configs(self):
|
def warm_configs(self):
|
||||||
for pw_key in WARMUP_PWS:
|
warm_pws = list(WARMUP_PWS)
|
||||||
self.cfg.get("passwords", pw_key)
|
|
||||||
driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
||||||
if driver_canon == 'xenserver':
|
if driver_canon == 'xenserver':
|
||||||
self.cfg.get("passwords", "xenapi_connection")
|
warm_pws.append('xenapi_connection')
|
||||||
|
for pw_key in warm_pws:
|
||||||
|
self.pw_gen.get_password(pw_key)
|
||||||
|
|
||||||
def _get_config_files(self):
|
def _get_config_files(self):
|
||||||
return list(CONFIGS)
|
return list(CONFIGS)
|
||||||
@ -317,7 +304,7 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
(_, contents) = utils.load_template(self.component_name, NET_INIT_CONF)
|
(_, contents) = utils.load_template(self.component_name, NET_INIT_CONF)
|
||||||
params = self._get_param_map(NET_INIT_CONF)
|
params = self._get_param_map(NET_INIT_CONF)
|
||||||
contents = utils.param_replace(contents, params, True)
|
contents = utils.param_replace(contents, params, True)
|
||||||
tgt_fn = sh.joinpths(self.bindir, NET_INIT_CONF)
|
tgt_fn = sh.joinpths(self.bin_dir, NET_INIT_CONF)
|
||||||
sh.write_file(tgt_fn, contents)
|
sh.write_file(tgt_fn, contents)
|
||||||
sh.chmod(tgt_fn, 0755)
|
sh.chmod(tgt_fn, 0755)
|
||||||
self.tracewriter.file_touched(tgt_fn)
|
self.tracewriter.file_touched(tgt_fn)
|
||||||
@ -325,18 +312,18 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
def _sync_db(self):
|
def _sync_db(self):
|
||||||
LOG.info("Syncing the database with nova.")
|
LOG.info("Syncing the database with nova.")
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['BINDIR'] = self.bindir
|
mp['BIN_DIR'] = self.bin_dir
|
||||||
mp['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
mp['CFGFILE'] = sh.joinpths(self.cfg_dir, API_CONF)
|
||||||
utils.execute_template(*DB_SYNC_CMD, params=mp)
|
utils.execute_template(*DB_SYNC_CMD, params=mp)
|
||||||
|
|
||||||
def post_install(self):
|
def post_install(self):
|
||||||
comp.PythonInstallComponent.post_install(self)
|
comp.PythonInstallComponent.post_install(self)
|
||||||
#extra actions to do nova setup
|
# Extra actions to do nova setup
|
||||||
self._setup_db()
|
self._setup_db()
|
||||||
self._sync_db()
|
self._sync_db()
|
||||||
self._setup_cleaner()
|
self._setup_cleaner()
|
||||||
self._setup_network_initer()
|
self._setup_network_initer()
|
||||||
#check if we need to do the vol subcomponent
|
# Check if we need to do the vol subsystem
|
||||||
if self.volumes_enabled:
|
if self.volumes_enabled:
|
||||||
vol_maker = NovaVolumeConfigurator(self)
|
vol_maker = NovaVolumeConfigurator(self)
|
||||||
vol_maker.setup_volumes()
|
vol_maker.setup_volumes()
|
||||||
@ -344,7 +331,7 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
def _setup_cleaner(self):
|
def _setup_cleaner(self):
|
||||||
LOG.info("Configuring cleaner template %s.", CLEANER_DATA_CONF)
|
LOG.info("Configuring cleaner template %s.", CLEANER_DATA_CONF)
|
||||||
(_, contents) = utils.load_template(self.component_name, CLEANER_DATA_CONF)
|
(_, contents) = utils.load_template(self.component_name, CLEANER_DATA_CONF)
|
||||||
tgt_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF)
|
tgt_fn = sh.joinpths(self.bin_dir, CLEANER_DATA_CONF)
|
||||||
sh.write_file(tgt_fn, contents)
|
sh.write_file(tgt_fn, contents)
|
||||||
sh.chmod(tgt_fn, 0755)
|
sh.chmod(tgt_fn, 0755)
|
||||||
self.tracewriter.file_touched(tgt_fn)
|
self.tracewriter.file_touched(tgt_fn)
|
||||||
@ -371,15 +358,15 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
return comp.PythonInstallComponent._get_source_config(self, PASTE_SOURCE_FN)
|
return comp.PythonInstallComponent._get_source_config(self, PASTE_SOURCE_FN)
|
||||||
elif config_fn == LOGGING_CONF:
|
elif config_fn == LOGGING_CONF:
|
||||||
name = LOGGING_SOURCE_FN
|
name = LOGGING_SOURCE_FN
|
||||||
srcfn = sh.joinpths(self.cfgdir, "nova", name)
|
srcfn = sh.joinpths(self.cfg_dir, "nova", name)
|
||||||
contents = sh.load_file(srcfn)
|
contents = sh.load_file(srcfn)
|
||||||
return (srcfn, contents)
|
return (srcfn, contents)
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
mp = dict()
|
mp = dict()
|
||||||
if config_fn == NET_INIT_CONF:
|
if config_fn == NET_INIT_CONF:
|
||||||
mp['NOVA_DIR'] = self.appdir
|
mp['NOVA_DIR'] = self.app_dir
|
||||||
mp['CFG_FILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
mp['CFG_FILE'] = sh.joinpths(self.cfg_dir, API_CONF)
|
||||||
mp['FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'floating_range', '172.24.4.224/28')
|
mp['FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'floating_range', '172.24.4.224/28')
|
||||||
mp['TEST_FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'test_floating_range', '192.168.253.0/29')
|
mp['TEST_FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'test_floating_range', '192.168.253.0/29')
|
||||||
mp['TEST_FLOATING_POOL'] = self.cfg.getdefaulted('nova', 'test_floating_pool', 'test')
|
mp['TEST_FLOATING_POOL'] = self.cfg.getdefaulted('nova', 'test_floating_pool', 'test')
|
||||||
@ -393,15 +380,16 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
configs_made = comp.PythonInstallComponent.configure(self)
|
configs_made = comp.PythonInstallComponent.configure(self)
|
||||||
self._generate_nova_conf()
|
self._generate_nova_conf()
|
||||||
configs_made += 1
|
configs_made += 1
|
||||||
# TODO: maybe this should be a subclass that handles these differences
|
|
||||||
driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
||||||
if (self.distro.name in POLICY_DISTROS) and driver_canon == 'libvirt':
|
# TODO maybe move this??
|
||||||
|
if driver_canon == 'libvirt' and self.distro.get_command('virt-policy', quiet=True):
|
||||||
|
(fn, contents) = self.distro.get_command('virt-policy')
|
||||||
dirs_made = list()
|
dirs_made = list()
|
||||||
with sh.Rooted(True):
|
with sh.Rooted(True):
|
||||||
dirs_made = sh.mkdirslist(sh.dirname(LIBVIRT_POLICY_FN))
|
dirs_made = sh.mkdirslist(sh.dirname(fn))
|
||||||
sh.write_file(LIBVIRT_POLICY_FN, LIBVIRT_POLICY_CONTENTS)
|
sh.write_file(fn, contents)
|
||||||
self.tracewriter.dirs_made(*dirs_made)
|
self.tracewriter.dirs_made(*dirs_made)
|
||||||
self.tracewriter.cfg_file_written(LIBVIRT_POLICY_FN)
|
self.tracewriter.cfg_file_written(fn)
|
||||||
configs_made += 1
|
configs_made += 1
|
||||||
return configs_made
|
return configs_made
|
||||||
|
|
||||||
@ -409,16 +397,16 @@ class NovaInstaller(comp.PythonInstallComponent):
|
|||||||
class NovaRuntime(comp.PythonRuntime):
|
class NovaRuntime(comp.PythonRuntime):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonRuntime.__init__(self, *args, **kargs)
|
comp.PythonRuntime.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
|
|
||||||
def _setup_network_init(self):
|
def _setup_network_init(self):
|
||||||
tgt_fn = sh.joinpths(self.bindir, NET_INIT_CONF)
|
tgt_fn = sh.joinpths(self.bin_dir, NET_INIT_CONF)
|
||||||
if sh.isfile(tgt_fn):
|
if sh.isfile(tgt_fn):
|
||||||
LOG.info("Creating your nova network to be used with instances.")
|
LOG.info("Creating your nova network to be used with instances.")
|
||||||
#still there, run it
|
# If still there, run it
|
||||||
#these environment additions are important
|
# these environment additions are important
|
||||||
#in that they eventually affect how this script runs
|
# in that they eventually affect how this script runs
|
||||||
if utils.service_enabled(settings.QUANTUM, self.instances, False):
|
if utils.service_enabled(settings.QUANTUM, self.instances, False):
|
||||||
LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO))
|
LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO))
|
||||||
sh.sleep(WAIT_ONLINE_TO)
|
sh.sleep(WAIT_ONLINE_TO)
|
||||||
@ -433,20 +421,17 @@ class NovaRuntime(comp.PythonRuntime):
|
|||||||
def post_start(self):
|
def post_start(self):
|
||||||
self._setup_network_init()
|
self._setup_network_init()
|
||||||
|
|
||||||
def get_dependencies(self):
|
def known_subsystems(self):
|
||||||
deps = comp.PythonRuntime.get_dependencies(self)
|
return SUBSYSTEMS
|
||||||
# FIXME: This should come from a persona.
|
|
||||||
if utils.service_enabled(settings.QUANTUM, self.instances, False):
|
|
||||||
deps.append(settings.QUANTUM)
|
|
||||||
return deps
|
|
||||||
|
|
||||||
def _get_apps_to_start(self):
|
def _get_apps_to_start(self):
|
||||||
result = [{'name': app_name,
|
apps = list()
|
||||||
'path': sh.joinpths(self.bindir, app_name),
|
for subsys in self.desired_subsystems:
|
||||||
}
|
app = dict()
|
||||||
for app_name in sorted(APP_OPTIONS.keys())
|
app['name'] = SUB_COMPONENT_NAME_MAP[subsys]
|
||||||
]
|
app['path'] = sh.joinpths(self.bin_dir, app['name'])
|
||||||
return result
|
apps.append(app)
|
||||||
|
return apps
|
||||||
|
|
||||||
def pre_start(self):
|
def pre_start(self):
|
||||||
# Let the parent class do its thing
|
# Let the parent class do its thing
|
||||||
@ -455,27 +440,27 @@ class NovaRuntime(comp.PythonRuntime):
|
|||||||
if virt_driver == 'libvirt':
|
if virt_driver == 'libvirt':
|
||||||
virt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
|
virt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
|
||||||
LOG.info("Checking that your selected libvirt virtualization type [%s] is working and running." % (virt_type))
|
LOG.info("Checking that your selected libvirt virtualization type [%s] is working and running." % (virt_type))
|
||||||
if not virsh.virt_ok(virt_type, self.distro.name):
|
if not virsh.virt_ok(virt_type, self.distro):
|
||||||
msg = ("Libvirt type %s for distro %s does not seem to be active or configured correctly, "
|
msg = ("Libvirt type %s does not seem to be active or configured correctly, "
|
||||||
"perhaps you should be using %s instead." % (virt_type, self.distro.name, DEF_VIRT_TYPE))
|
"perhaps you should be using %s instead." % (virt_type, DEF_VIRT_TYPE))
|
||||||
raise exceptions.StartException(msg)
|
raise exceptions.StartException(msg)
|
||||||
virsh.restart(self.distro.name)
|
virsh.restart(self.distro)
|
||||||
|
|
||||||
def _get_param_map(self, app_name):
|
def _get_param_map(self, app_name):
|
||||||
params = comp.PythonRuntime._get_param_map(self, app_name)
|
params = comp.PythonRuntime._get_param_map(self, app_name)
|
||||||
params['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
params['CFGFILE'] = sh.joinpths(self.cfg_dir, API_CONF)
|
||||||
return params
|
return params
|
||||||
|
|
||||||
def _get_app_options(self, app):
|
def _get_app_options(self, app):
|
||||||
return APP_OPTIONS.get(app)
|
return APP_OPTIONS.get(app)
|
||||||
|
|
||||||
|
|
||||||
#this will configure nova volumes which in a developer box
|
# This will configure nova volumes which in a developer box
|
||||||
#is a volume group (lvm) that are backed by a loopback file
|
# is a volume group (lvm) that are backed by a loopback file
|
||||||
class NovaVolumeConfigurator(object):
|
class NovaVolumeConfigurator(object):
|
||||||
def __init__(self, ni):
|
def __init__(self, ni):
|
||||||
self.cfg = ni.cfg
|
self.cfg = ni.cfg
|
||||||
self.appdir = ni.appdir
|
self.app_dir = ni.app_dir
|
||||||
self.distro = ni.distro
|
self.distro = ni.distro
|
||||||
|
|
||||||
def setup_volumes(self):
|
def setup_volumes(self):
|
||||||
@ -484,7 +469,7 @@ class NovaVolumeConfigurator(object):
|
|||||||
def _setup_vol_groups(self):
|
def _setup_vol_groups(self):
|
||||||
LOG.info("Attempting to setup volume groups for nova volume management.")
|
LOG.info("Attempting to setup volume groups for nova volume management.")
|
||||||
mp = dict()
|
mp = dict()
|
||||||
backing_file = self.cfg.getdefaulted('nova', 'volume_backing_file', sh.joinpths(self.appdir, 'nova-volumes-backing-file'))
|
backing_file = self.cfg.getdefaulted('nova', 'volume_backing_file', sh.joinpths(self.app_dir, 'nova-volumes-backing-file'))
|
||||||
vol_group = self.cfg.getdefaulted('nova', 'volume_group', 'nova-volumes')
|
vol_group = self.cfg.getdefaulted('nova', 'volume_group', 'nova-volumes')
|
||||||
backing_file_size = utils.to_bytes(self.cfg.getdefaulted('nova', 'volume_backing_file_size', '2052M'))
|
backing_file_size = utils.to_bytes(self.cfg.getdefaulted('nova', 'volume_backing_file_size', '2052M'))
|
||||||
mp['VOLUME_GROUP'] = vol_group
|
mp['VOLUME_GROUP'] = vol_group
|
||||||
@ -511,7 +496,9 @@ class NovaVolumeConfigurator(object):
|
|||||||
# logical volumes
|
# logical volumes
|
||||||
self._process_lvs(mp)
|
self._process_lvs(mp)
|
||||||
# Finish off by restarting tgt, and ignore any errors
|
# Finish off by restarting tgt, and ignore any errors
|
||||||
utils.execute_template(*RESTART_TGT_CMD[self.distro.name], check_exit_code=False)
|
cmdrestart = self.distro.get_command('iscsi', 'restart', quiet=True)
|
||||||
|
if cmdrestart:
|
||||||
|
sh.execute(*cmdrestart, run_as_root=True, check_exit_code=False)
|
||||||
|
|
||||||
def _process_lvs(self, mp):
|
def _process_lvs(self, mp):
|
||||||
LOG.info("Attempting to setup logical volumes for nova volume management.")
|
LOG.info("Attempting to setup logical volumes for nova volume management.")
|
||||||
@ -547,12 +534,12 @@ class NovaConfConfigurator(object):
|
|||||||
self.cfg = ni.cfg
|
self.cfg = ni.cfg
|
||||||
self.pw_gen = ni.pw_gen
|
self.pw_gen = ni.pw_gen
|
||||||
self.instances = ni.instances
|
self.instances = ni.instances
|
||||||
self.component_root = ni.component_root
|
self.component_dir = ni.component_dir
|
||||||
self.appdir = ni.appdir
|
self.app_dir = ni.app_dir
|
||||||
self.tracewriter = ni.tracewriter
|
self.tracewriter = ni.tracewriter
|
||||||
self.paste_conf_fn = ni.paste_conf_fn
|
self.paste_conf_fn = ni.paste_conf_fn
|
||||||
self.distro = ni.distro
|
self.distro = ni.distro
|
||||||
self.cfgdir = ni.cfgdir
|
self.cfg_dir = ni.cfg_dir
|
||||||
self.xvnc_enabled = ni.xvnc_enabled
|
self.xvnc_enabled = ni.xvnc_enabled
|
||||||
self.volumes_enabled = ni.volumes_enabled
|
self.volumes_enabled = ni.volumes_enabled
|
||||||
self.novnc_enabled = utils.service_enabled(settings.NOVNC, self.instances)
|
self.novnc_enabled = utils.service_enabled(settings.NOVNC, self.instances)
|
||||||
@ -564,13 +551,12 @@ class NovaConfConfigurator(object):
|
|||||||
return self.cfg.getdefaulted('nova', name, default)
|
return self.cfg.getdefaulted('nova', name, default)
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
#everything built goes in here
|
# Everything built goes in here
|
||||||
nova_conf = NovaConf()
|
nova_conf = NovaConf()
|
||||||
|
|
||||||
#used more than once
|
# Used more than once so we calculate it ahead of time
|
||||||
hostip = self.cfg.get('host', 'ip')
|
hostip = self.cfg.get('host', 'ip')
|
||||||
|
|
||||||
#verbose on?
|
|
||||||
if self._getbool('verbose'):
|
if self._getbool('verbose'):
|
||||||
nova_conf.add('verbose', True)
|
nova_conf.add('verbose', True)
|
||||||
|
|
||||||
@ -588,79 +574,79 @@ class NovaConfConfigurator(object):
|
|||||||
sh.mkdir(full_logdir)
|
sh.mkdir(full_logdir)
|
||||||
sh.chmod(full_logdir, 0777)
|
sh.chmod(full_logdir, 0777)
|
||||||
|
|
||||||
#allow the admin api?
|
# Allow the admin api?
|
||||||
if self._getbool('allow_admin_api'):
|
if self._getbool('allow_admin_api'):
|
||||||
nova_conf.add('allow_admin_api', True)
|
nova_conf.add('allow_admin_api', True)
|
||||||
|
|
||||||
#??
|
# FIXME: ??
|
||||||
nova_conf.add('allow_resize_to_same_host', True)
|
nova_conf.add('allow_resize_to_same_host', True)
|
||||||
|
|
||||||
#which scheduler do u want?
|
# Which scheduler do u want?
|
||||||
nova_conf.add('compute_scheduler_driver', self._getstr('scheduler', DEF_SCHEDULER))
|
nova_conf.add('compute_scheduler_driver', self._getstr('scheduler', DEF_SCHEDULER))
|
||||||
|
|
||||||
#setup network settings
|
# Setup any network settings
|
||||||
self._configure_network_settings(nova_conf)
|
self._configure_network_settings(nova_conf)
|
||||||
|
|
||||||
#setup nova volume settings
|
# Setup nova volume settings
|
||||||
if self.volumes_enabled:
|
if self.volumes_enabled:
|
||||||
self._configure_vols(nova_conf)
|
self._configure_vols(nova_conf)
|
||||||
|
|
||||||
#where we are running
|
# The ip of where we are running
|
||||||
nova_conf.add('my_ip', hostip)
|
nova_conf.add('my_ip', hostip)
|
||||||
|
|
||||||
#setup your sql connection
|
# Setup your sql connection
|
||||||
db_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
db_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
|
||||||
nova_conf.add('sql_connection', db_dsn)
|
nova_conf.add('sql_connection', db_dsn)
|
||||||
|
|
||||||
#configure anything libvirt releated?
|
# Configure anything libvirt related?
|
||||||
virt_driver = _canon_virt_driver(self._getstr('virt_driver'))
|
virt_driver = _canon_virt_driver(self._getstr('virt_driver'))
|
||||||
if virt_driver == 'libvirt':
|
if virt_driver == 'libvirt':
|
||||||
libvirt_type = _canon_libvirt_type(self._getstr('libvirt_type'))
|
libvirt_type = _canon_libvirt_type(self._getstr('libvirt_type'))
|
||||||
self._configure_libvirt(libvirt_type, nova_conf)
|
self._configure_libvirt(libvirt_type, nova_conf)
|
||||||
|
|
||||||
#how instances will be presented
|
# How instances will be presented
|
||||||
instance_template = self._getstr('instance_name_prefix') + self._getstr('instance_name_postfix')
|
instance_template = self._getstr('instance_name_prefix') + self._getstr('instance_name_postfix')
|
||||||
if not instance_template:
|
if not instance_template:
|
||||||
instance_template = DEF_INSTANCE_TEMPL
|
instance_template = DEF_INSTANCE_TEMPL
|
||||||
nova_conf.add('instance_name_template', instance_template)
|
nova_conf.add('instance_name_template', instance_template)
|
||||||
|
|
||||||
#enable the standard extensions
|
# Enable the standard extensions
|
||||||
nova_conf.add('osapi_compute_extension', STD_COMPUTE_EXTS)
|
nova_conf.add('osapi_compute_extension', STD_COMPUTE_EXTS)
|
||||||
|
|
||||||
#auth will be using keystone
|
# Auth will be using keystone
|
||||||
nova_conf.add('auth_strategy', 'keystone')
|
nova_conf.add('auth_strategy', 'keystone')
|
||||||
|
|
||||||
#vnc settings setup
|
# Vnc settings setup
|
||||||
self._configure_vnc(nova_conf)
|
self._configure_vnc(nova_conf)
|
||||||
|
|
||||||
#where our paste config is
|
# Where our paste config is
|
||||||
nova_conf.add('api_paste_config', self.paste_conf_fn)
|
nova_conf.add('api_paste_config', self.paste_conf_fn)
|
||||||
|
|
||||||
#what our imaging service will be
|
# What our imaging service will be
|
||||||
self._configure_image_service(nova_conf, hostip)
|
self._configure_image_service(nova_conf, hostip)
|
||||||
|
|
||||||
#ec2 / s3 stuff
|
# Configs for ec2 / s3 stuff
|
||||||
nova_conf.add('ec2_dmz_host', self._getstr('ec2_dmz_host', hostip))
|
nova_conf.add('ec2_dmz_host', self._getstr('ec2_dmz_host', hostip))
|
||||||
nova_conf.add('s3_host', hostip)
|
nova_conf.add('s3_host', hostip)
|
||||||
|
|
||||||
#how is your rabbit setup?
|
# How is your rabbit setup?
|
||||||
nova_conf.add('rabbit_host', self.cfg.getdefaulted('default', 'rabbit_host', hostip))
|
nova_conf.add('rabbit_host', self.cfg.getdefaulted('default', 'rabbit_host', hostip))
|
||||||
nova_conf.add('rabbit_password', self.cfg.get("passwords", "rabbit"))
|
nova_conf.add('rabbit_password', self.cfg.get("passwords", "rabbit"))
|
||||||
|
|
||||||
#where instances will be stored
|
# Where instances will be stored
|
||||||
instances_path = self._getstr('instances_path', sh.joinpths(self.component_root, 'instances'))
|
instances_path = self._getstr('instances_path', sh.joinpths(self.component_dir, 'instances'))
|
||||||
self._configure_instances_path(instances_path, nova_conf)
|
self._configure_instances_path(instances_path, nova_conf)
|
||||||
|
|
||||||
#is this a multihost setup?
|
# Is this a multihost setup?
|
||||||
self._configure_multihost(nova_conf)
|
self._configure_multihost(nova_conf)
|
||||||
|
|
||||||
#enable syslog??
|
# Enable syslog??
|
||||||
self._configure_syslog(nova_conf)
|
self._configure_syslog(nova_conf)
|
||||||
|
|
||||||
#handle any virt driver specifics
|
# Handle any virt driver specifics
|
||||||
self._configure_virt_driver(nova_conf)
|
self._configure_virt_driver(nova_conf)
|
||||||
|
|
||||||
#and extract to finish
|
# Annnnnd extract to finish
|
||||||
return self._get_content(nova_conf)
|
return self._get_content(nova_conf)
|
||||||
|
|
||||||
def _get_extra(self, key):
|
def _get_extra(self, key):
|
||||||
@ -707,11 +693,11 @@ class NovaConfConfigurator(object):
|
|||||||
return generated_content
|
return generated_content
|
||||||
|
|
||||||
def _configure_image_service(self, nova_conf, hostip):
|
def _configure_image_service(self, nova_conf, hostip):
|
||||||
#what image service we will use
|
# What image service we will u be using sir?
|
||||||
img_service = self._getstr('img_service', DEF_IMAGE_SERVICE)
|
img_service = self._getstr('img_service', DEF_IMAGE_SERVICE)
|
||||||
nova_conf.add('image_service', img_service)
|
nova_conf.add('image_service', img_service)
|
||||||
|
|
||||||
#where is glance located?
|
# If glance then where is it?
|
||||||
if img_service.lower().find("glance") != -1:
|
if img_service.lower().find("glance") != -1:
|
||||||
glance_api_server = self._getstr('glance_server', (DEF_GLANCE_SERVER % (hostip)))
|
glance_api_server = self._getstr('glance_server', (DEF_GLANCE_SERVER % (hostip)))
|
||||||
nova_conf.add('glance_api_servers', glance_api_server)
|
nova_conf.add('glance_api_servers', glance_api_server)
|
||||||
@ -747,7 +733,7 @@ class NovaConfConfigurator(object):
|
|||||||
nova_conf.add('iscsi_helper', 'tgtadm')
|
nova_conf.add('iscsi_helper', 'tgtadm')
|
||||||
|
|
||||||
def _configure_network_settings(self, nova_conf):
|
def _configure_network_settings(self, nova_conf):
|
||||||
#TODO this might not be right....
|
# TODO this might not be right....
|
||||||
if utils.service_enabled(settings.QUANTUM, self.instances, False):
|
if utils.service_enabled(settings.QUANTUM, self.instances, False):
|
||||||
nova_conf.add('network_manager', QUANTUM_MANAGER)
|
nova_conf.add('network_manager', QUANTUM_MANAGER)
|
||||||
hostip = self.cfg.get('host', 'ip')
|
hostip = self.cfg.get('host', 'ip')
|
||||||
@ -764,10 +750,11 @@ class NovaConfConfigurator(object):
|
|||||||
else:
|
else:
|
||||||
nova_conf.add('network_manager', NET_MANAGER_TEMPLATE % (self._getstr('network_manager', DEF_NET_MANAGER)))
|
nova_conf.add('network_manager', NET_MANAGER_TEMPLATE % (self._getstr('network_manager', DEF_NET_MANAGER)))
|
||||||
|
|
||||||
#dhcp bridge stuff???
|
# Configs dhcp bridge stuff???
|
||||||
nova_conf.add('dhcpbridge_flagfile', sh.joinpths(self.cfgdir, API_CONF))
|
# TODO: why is this the same as the nova.conf?
|
||||||
|
nova_conf.add('dhcpbridge_flagfile', sh.joinpths(self.cfg_dir, API_CONF))
|
||||||
|
|
||||||
#Network prefix for the IP network that all the projects for future VM guests reside on. Example: 192.168.0.0/12
|
# Network prefix for the IP network that all the projects for future VM guests reside on. Example: 192.168.0.0/12
|
||||||
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
||||||
|
|
||||||
# The value for vlan_interface may default to the the current value
|
# The value for vlan_interface may default to the the current value
|
||||||
@ -775,7 +762,7 @@ class NovaConfConfigurator(object):
|
|||||||
public_interface = self._getstr('public_interface')
|
public_interface = self._getstr('public_interface')
|
||||||
vlan_interface = self._getstr('vlan_interface', public_interface)
|
vlan_interface = self._getstr('vlan_interface', public_interface)
|
||||||
|
|
||||||
#do a little check to make sure actually have that interface set...
|
# Do a little check to make sure actually have that interface/s
|
||||||
if not utils.is_interface(public_interface):
|
if not utils.is_interface(public_interface):
|
||||||
msg = "Public interface %s is not a known interface" % (public_interface)
|
msg = "Public interface %s is not a known interface" % (public_interface)
|
||||||
raise exceptions.ConfigException(msg)
|
raise exceptions.ConfigException(msg)
|
||||||
@ -787,7 +774,7 @@ class NovaConfConfigurator(object):
|
|||||||
nova_conf.add('public_interface', public_interface)
|
nova_conf.add('public_interface', public_interface)
|
||||||
nova_conf.add('vlan_interface', vlan_interface)
|
nova_conf.add('vlan_interface', vlan_interface)
|
||||||
|
|
||||||
#This forces dnsmasq to update its leases table when an instance is terminated.
|
# This forces dnsmasq to update its leases table when an instance is terminated.
|
||||||
nova_conf.add('force_dhcp_release', True)
|
nova_conf.add('force_dhcp_release', True)
|
||||||
|
|
||||||
def _configure_syslog(self, nova_conf):
|
def _configure_syslog(self, nova_conf):
|
||||||
@ -812,11 +799,11 @@ class NovaConfConfigurator(object):
|
|||||||
pass
|
pass
|
||||||
nova_conf.add('libvirt_type', virt_type)
|
nova_conf.add('libvirt_type', virt_type)
|
||||||
|
|
||||||
#configures any virt driver settings
|
# Configures any virt driver settings
|
||||||
def _configure_virt_driver(self, nova_conf):
|
def _configure_virt_driver(self, nova_conf):
|
||||||
drive_canon = _canon_virt_driver(self._getstr('virt_driver'))
|
drive_canon = _canon_virt_driver(self._getstr('virt_driver'))
|
||||||
nova_conf.add('connection_type', VIRT_DRIVER_CON_MAP.get(drive_canon, drive_canon))
|
nova_conf.add('connection_type', VIRT_DRIVER_CON_MAP.get(drive_canon, drive_canon))
|
||||||
#special driver settings
|
# Special driver settings
|
||||||
if drive_canon == 'xenserver':
|
if drive_canon == 'xenserver':
|
||||||
nova_conf.add('xenapi_connection_url', self._getstr('xa_connection_url', XA_DEF_CONNECTION_URL))
|
nova_conf.add('xenapi_connection_url', self._getstr('xa_connection_url', XA_DEF_CONNECTION_URL))
|
||||||
nova_conf.add('xenapi_connection_username', self._getstr('xa_connection_username', XA_DEF_USER))
|
nova_conf.add('xenapi_connection_username', self._getstr('xa_connection_username', XA_DEF_USER))
|
||||||
@ -840,7 +827,7 @@ class NovaConfConfigurator(object):
|
|||||||
nova_conf.add('flat_interface', flat_interface)
|
nova_conf.add('flat_interface', flat_interface)
|
||||||
|
|
||||||
|
|
||||||
# This class represents the data in the nova config file
|
# This class represents the data/format of the nova config file
|
||||||
class NovaConf(object):
|
class NovaConf(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.lines = list()
|
self.lines = list()
|
||||||
|
@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
from devstack import component as comp
|
from devstack import component as comp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.NOVA_CLIENT
|
|
||||||
LOG = logging.getLogger("devstack.components.nova_client")
|
LOG = logging.getLogger("devstack.components.nova_client")
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,17 +22,15 @@ from devstack import utils
|
|||||||
|
|
||||||
from devstack.components import nova
|
from devstack.components import nova
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.NOVNC
|
|
||||||
LOG = logging.getLogger("devstack.components.novnc")
|
LOG = logging.getLogger("devstack.components.novnc")
|
||||||
|
|
||||||
#where the application is really
|
# Where the application is really
|
||||||
UTIL_DIR = 'utils'
|
UTIL_DIR = 'utils'
|
||||||
|
|
||||||
VNC_PROXY_APP = 'nova-novncproxy'
|
VNC_PROXY_APP = 'nova-novncproxy'
|
||||||
APP_OPTIONS = {
|
APP_OPTIONS = {
|
||||||
#this reaches into the nova configuration file
|
# This reaches into the nova configuration file
|
||||||
#TODO can we stop that?
|
# TODO can we stop that?
|
||||||
VNC_PROXY_APP: ['--flagfile', '%NOVA_CONF%', '--web', '.'],
|
VNC_PROXY_APP: ['--flagfile', '%NOVA_CONF%', '--web', '.'],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,16 +65,16 @@ class NoVNCRuntime(comp.ProgramRuntime):
|
|||||||
for app_name in APP_OPTIONS.keys():
|
for app_name in APP_OPTIONS.keys():
|
||||||
apps.append({
|
apps.append({
|
||||||
'name': app_name,
|
'name': app_name,
|
||||||
'path': sh.joinpths(self.appdir, UTIL_DIR, app_name),
|
'path': sh.joinpths(self.app_dir, UTIL_DIR, app_name),
|
||||||
})
|
})
|
||||||
return apps
|
return apps
|
||||||
|
|
||||||
def _get_param_map(self, app_name):
|
def _get_param_map(self, app_name):
|
||||||
root_params = comp.ProgramRuntime._get_param_map(self, app_name)
|
root_params = comp.ProgramRuntime._get_param_map(self, app_name)
|
||||||
if app_name == VNC_PROXY_APP and utils.service_enabled(settings.NOVA, self.instances, False):
|
if app_name == VNC_PROXY_APP and utils.service_enabled(settings.NOVA, self.instances, False):
|
||||||
#have to reach into the nova conf (puke)
|
# FIXME: Have to reach into the nova conf (puke)
|
||||||
nova_runtime = self.instances[settings.NOVA]
|
nova_runtime = self.instances[settings.NOVA]
|
||||||
root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfgdir, nova.API_CONF)
|
root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfg_dir, nova.API_CONF)
|
||||||
return root_params
|
return root_params
|
||||||
|
|
||||||
def _get_app_options(self, app):
|
def _get_app_options(self, app):
|
||||||
|
@ -25,16 +25,13 @@ from devstack import utils
|
|||||||
|
|
||||||
from devstack.components import db
|
from devstack.components import db
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.QUANTUM
|
|
||||||
LOG = logging.getLogger("devstack.components.quantum")
|
LOG = logging.getLogger("devstack.components.quantum")
|
||||||
|
|
||||||
#vswitch pkgs
|
# Openvswitch special settings
|
||||||
VSWITCH_PLUGIN = 'openvswitch'
|
VSWITCH_PLUGIN = 'openvswitch'
|
||||||
PKG_VSWITCH = "quantum-openvswitch.json"
|
|
||||||
V_PROVIDER = "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin"
|
V_PROVIDER = "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin"
|
||||||
|
|
||||||
#config files (some only modified if running as openvswitch)
|
# Config files (some only modified if running as openvswitch)
|
||||||
PLUGIN_CONF = "plugins.ini"
|
PLUGIN_CONF = "plugins.ini"
|
||||||
QUANTUM_CONF = 'quantum.conf'
|
QUANTUM_CONF = 'quantum.conf'
|
||||||
PLUGIN_LOC = ['etc']
|
PLUGIN_LOC = ['etc']
|
||||||
@ -43,24 +40,20 @@ AGENT_LOC = ["etc", "quantum", "plugins", "openvswitch"]
|
|||||||
AGENT_BIN_LOC = ["quantum", "plugins", "openvswitch", 'agent']
|
AGENT_BIN_LOC = ["quantum", "plugins", "openvswitch", 'agent']
|
||||||
CONFIG_FILES = [PLUGIN_CONF, AGENT_CONF]
|
CONFIG_FILES = [PLUGIN_CONF, AGENT_CONF]
|
||||||
|
|
||||||
#this db will be dropped and created
|
# This db will be dropped and created
|
||||||
DB_NAME = 'ovs_quantum'
|
DB_NAME = 'ovs_quantum'
|
||||||
|
|
||||||
#opensvswitch bridge setup/teardown/name commands
|
# Opensvswitch bridge setup/teardown/name commands
|
||||||
OVS_BRIDGE_DEL = ['ovs-vsctl', '--no-wait', '--', '--if-exists', 'del-br', '%OVS_BRIDGE%']
|
OVS_BRIDGE_DEL = ['ovs-vsctl', '--no-wait', '--', '--if-exists', 'del-br', '%OVS_BRIDGE%']
|
||||||
OVS_BRIDGE_ADD = ['ovs-vsctl', '--no-wait', 'add-br', '%OVS_BRIDGE%']
|
OVS_BRIDGE_ADD = ['ovs-vsctl', '--no-wait', 'add-br', '%OVS_BRIDGE%']
|
||||||
OVS_BRIDGE_EXTERN_ID = ['ovs-vsctl', '--no-wait', 'br-set-external-id', '%OVS_BRIDGE%', 'bridge-id', '%OVS_EXTERNAL_ID%']
|
OVS_BRIDGE_EXTERN_ID = ['ovs-vsctl', '--no-wait', 'br-set-external-id', '%OVS_BRIDGE%', 'bridge-id', '%OVS_EXTERNAL_ID%']
|
||||||
OVS_BRIDGE_CMDS = [OVS_BRIDGE_DEL, OVS_BRIDGE_ADD, OVS_BRIDGE_EXTERN_ID]
|
OVS_BRIDGE_CMDS = [OVS_BRIDGE_DEL, OVS_BRIDGE_ADD, OVS_BRIDGE_EXTERN_ID]
|
||||||
|
|
||||||
#special component options
|
# Subdirs of the downloaded
|
||||||
QUANTUM_SERVICE = 'q-svc'
|
|
||||||
QUANTUM_AGENT = 'q-agt'
|
|
||||||
|
|
||||||
#subdirs of the downloaded
|
|
||||||
CONFIG_DIR = 'etc'
|
CONFIG_DIR = 'etc'
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
|
|
||||||
#what to start (only if openvswitch enabled)
|
# What to start (only if openvswitch enabled)
|
||||||
APP_Q_SERVER = 'quantum-server'
|
APP_Q_SERVER = 'quantum-server'
|
||||||
APP_Q_AGENT = 'ovs_quantum_agent.py'
|
APP_Q_AGENT = 'ovs_quantum_agent.py'
|
||||||
APP_OPTIONS = {
|
APP_OPTIONS = {
|
||||||
@ -81,15 +74,8 @@ class QuantumInstaller(comp.PkgInstallComponent):
|
|||||||
self.q_vswitch_service = False
|
self.q_vswitch_service = False
|
||||||
plugin = self.cfg.getdefaulted("quantum", "q_plugin", VSWITCH_PLUGIN)
|
plugin = self.cfg.getdefaulted("quantum", "q_plugin", VSWITCH_PLUGIN)
|
||||||
if plugin == VSWITCH_PLUGIN:
|
if plugin == VSWITCH_PLUGIN:
|
||||||
#default to on if not specified
|
|
||||||
self.q_vswitch_agent = True
|
self.q_vswitch_agent = True
|
||||||
self.q_vswitch_service = True
|
self.q_vswitch_service = True
|
||||||
# else:
|
|
||||||
# #only turn on if requested
|
|
||||||
# if QUANTUM_SERVICE in self.component_opts:
|
|
||||||
# self.q_vswitch_service = True
|
|
||||||
# if QUANTUM_AGENT in self.component_opts:
|
|
||||||
# self.q_vswitch_agent = True
|
|
||||||
|
|
||||||
def _get_download_locations(self):
|
def _get_download_locations(self):
|
||||||
places = list()
|
places = list()
|
||||||
@ -99,34 +85,22 @@ class QuantumInstaller(comp.PkgInstallComponent):
|
|||||||
})
|
})
|
||||||
return places
|
return places
|
||||||
|
|
||||||
def get_dependencies(self):
|
|
||||||
common_deps = comp.PkgInstallComponent.get_dependencies(self)
|
|
||||||
add_deps = list()
|
|
||||||
# FIXME: This should come from a persona.
|
|
||||||
if self.q_vswitch_agent:
|
|
||||||
#just need the client
|
|
||||||
add_deps.append(settings.QUANTUM_CLIENT)
|
|
||||||
if self.q_vswitch_service:
|
|
||||||
#in this case we need the db
|
|
||||||
add_deps.append(settings.DB)
|
|
||||||
return common_deps + add_deps
|
|
||||||
|
|
||||||
def _get_config_files(self):
|
def _get_config_files(self):
|
||||||
return list(CONFIG_FILES)
|
return list(CONFIG_FILES)
|
||||||
|
|
||||||
def _get_target_config_name(self, config_fn):
|
def _get_target_config_name(self, config_fn):
|
||||||
if config_fn == PLUGIN_CONF:
|
if config_fn == PLUGIN_CONF:
|
||||||
tgt_loc = [self.appdir] + PLUGIN_LOC + [config_fn]
|
tgt_loc = [self.app_dir] + PLUGIN_LOC + [config_fn]
|
||||||
return sh.joinpths(*tgt_loc)
|
return sh.joinpths(*tgt_loc)
|
||||||
elif config_fn == AGENT_CONF:
|
elif config_fn == AGENT_CONF:
|
||||||
tgt_loc = [self.appdir] + AGENT_LOC + [config_fn]
|
tgt_loc = [self.app_dir] + AGENT_LOC + [config_fn]
|
||||||
return sh.joinpths(*tgt_loc)
|
return sh.joinpths(*tgt_loc)
|
||||||
else:
|
else:
|
||||||
return comp.PkgInstallComponent._get_target_config_name(self, config_fn)
|
return comp.PkgInstallComponent._get_target_config_name(self, config_fn)
|
||||||
|
|
||||||
def _config_adjust(self, contents, config_fn):
|
def _config_adjust(self, contents, config_fn):
|
||||||
if config_fn == PLUGIN_CONF and self.q_vswitch_service:
|
if config_fn == PLUGIN_CONF and self.q_vswitch_service:
|
||||||
#need to fix the "Quantum plugin provider module"
|
# Need to fix the "Quantum plugin provider module"
|
||||||
newcontents = contents
|
newcontents = contents
|
||||||
with io.BytesIO(contents) as stream:
|
with io.BytesIO(contents) as stream:
|
||||||
config = cfg.IgnoreMissingConfigParser()
|
config = cfg.IgnoreMissingConfigParser()
|
||||||
@ -140,7 +114,7 @@ class QuantumInstaller(comp.PkgInstallComponent):
|
|||||||
newcontents = cfg.add_header(config_fn, outputstream.getvalue())
|
newcontents = cfg.add_header(config_fn, outputstream.getvalue())
|
||||||
return newcontents
|
return newcontents
|
||||||
elif config_fn == AGENT_CONF and self.q_vswitch_agent:
|
elif config_fn == AGENT_CONF and self.q_vswitch_agent:
|
||||||
#Need to adjust the sql connection
|
# Need to adjust the sql connection
|
||||||
newcontents = contents
|
newcontents = contents
|
||||||
with io.BytesIO(contents) as stream:
|
with io.BytesIO(contents) as stream:
|
||||||
config = cfg.IgnoreMissingConfigParser()
|
config = cfg.IgnoreMissingConfigParser()
|
||||||
@ -189,12 +163,12 @@ class QuantumInstaller(comp.PkgInstallComponent):
|
|||||||
|
|
||||||
def _get_source_config(self, config_fn):
|
def _get_source_config(self, config_fn):
|
||||||
if config_fn == PLUGIN_CONF:
|
if config_fn == PLUGIN_CONF:
|
||||||
srcloc = [self.appdir] + PLUGIN_LOC + [config_fn]
|
srcloc = [self.app_dir] + PLUGIN_LOC + [config_fn]
|
||||||
srcfn = sh.joinpths(*srcloc)
|
srcfn = sh.joinpths(*srcloc)
|
||||||
contents = sh.load_file(srcfn)
|
contents = sh.load_file(srcfn)
|
||||||
return (srcfn, contents)
|
return (srcfn, contents)
|
||||||
elif config_fn == AGENT_CONF:
|
elif config_fn == AGENT_CONF:
|
||||||
srcloc = [self.appdir] + AGENT_LOC + [config_fn]
|
srcloc = [self.app_dir] + AGENT_LOC + [config_fn]
|
||||||
srcfn = sh.joinpths(*srcloc)
|
srcfn = sh.joinpths(*srcloc)
|
||||||
contents = sh.load_file(srcfn)
|
contents = sh.load_file(srcfn)
|
||||||
return (srcfn, contents)
|
return (srcfn, contents)
|
||||||
@ -209,25 +183,19 @@ class QuantumRuntime(comp.ProgramRuntime):
|
|||||||
self.q_vswitch_service = False
|
self.q_vswitch_service = False
|
||||||
plugin = self.cfg.getdefaulted("quantum", "q_plugin", VSWITCH_PLUGIN)
|
plugin = self.cfg.getdefaulted("quantum", "q_plugin", VSWITCH_PLUGIN)
|
||||||
if plugin == VSWITCH_PLUGIN:
|
if plugin == VSWITCH_PLUGIN:
|
||||||
#default to on if not specified
|
# Default to on if not specified
|
||||||
self.q_vswitch_agent = True
|
self.q_vswitch_agent = True
|
||||||
self.q_vswitch_service = True
|
self.q_vswitch_service = True
|
||||||
# else:
|
|
||||||
# #only turn on if requested
|
|
||||||
# if QUANTUM_SERVICE in self.component_opts:
|
|
||||||
# self.q_vswitch_service = True
|
|
||||||
# if QUANTUM_AGENT in self.component_opts:
|
|
||||||
# self.q_vswitch_agent = True
|
|
||||||
|
|
||||||
def _get_apps_to_start(self):
|
def _get_apps_to_start(self):
|
||||||
app_list = comp.ProgramRuntime._get_apps_to_start(self)
|
app_list = comp.ProgramRuntime._get_apps_to_start(self)
|
||||||
if self.q_vswitch_service:
|
if self.q_vswitch_service:
|
||||||
app_list.append({
|
app_list.append({
|
||||||
'name': APP_Q_SERVER,
|
'name': APP_Q_SERVER,
|
||||||
'path': sh.joinpths(self.appdir, BIN_DIR, APP_Q_SERVER),
|
'path': sh.joinpths(self.app_dir, BIN_DIR, APP_Q_SERVER),
|
||||||
})
|
})
|
||||||
if self.q_vswitch_agent:
|
if self.q_vswitch_agent:
|
||||||
full_pth = [self.appdir] + AGENT_BIN_LOC + [APP_Q_AGENT]
|
full_pth = [self.app_dir] + AGENT_BIN_LOC + [APP_Q_AGENT]
|
||||||
app_list.append({
|
app_list.append({
|
||||||
'name': APP_Q_AGENT,
|
'name': APP_Q_AGENT,
|
||||||
'path': sh.joinpths(*full_pth)
|
'path': sh.joinpths(*full_pth)
|
||||||
@ -240,8 +208,8 @@ class QuantumRuntime(comp.ProgramRuntime):
|
|||||||
def _get_param_map(self, app_name):
|
def _get_param_map(self, app_name):
|
||||||
param_dict = comp.ProgramRuntime._get_param_map(self, app_name)
|
param_dict = comp.ProgramRuntime._get_param_map(self, app_name)
|
||||||
if app_name == APP_Q_AGENT:
|
if app_name == APP_Q_AGENT:
|
||||||
tgt_loc = [self.appdir] + AGENT_LOC + [AGENT_CONF]
|
tgt_loc = [self.app_dir] + AGENT_LOC + [AGENT_CONF]
|
||||||
param_dict['OVS_CONFIG_FILE'] = sh.joinpths(*tgt_loc)
|
param_dict['OVS_CONFIG_FILE'] = sh.joinpths(*tgt_loc)
|
||||||
elif app_name == APP_Q_SERVER:
|
elif app_name == APP_Q_SERVER:
|
||||||
param_dict['QUANTUM_CONFIG_FILE'] = sh.joinpths(self.appdir, CONFIG_DIR, QUANTUM_CONF)
|
param_dict['QUANTUM_CONFIG_FILE'] = sh.joinpths(self.app_dir, CONFIG_DIR, QUANTUM_CONF)
|
||||||
return param_dict
|
return param_dict
|
||||||
|
@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
from devstack import component as comp
|
from devstack import component as comp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.QUANTUM_CLIENT
|
|
||||||
LOG = logging.getLogger("devstack.components.quantum_client")
|
LOG = logging.getLogger("devstack.components.quantum_client")
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,27 +21,25 @@ from devstack import log as logging
|
|||||||
from devstack import settings
|
from devstack import settings
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.RABBIT
|
|
||||||
LOG = logging.getLogger("devstack.components.rabbit")
|
LOG = logging.getLogger("devstack.components.rabbit")
|
||||||
|
|
||||||
#hopefully these are distro independent..
|
# So far these are distro independent..
|
||||||
START_CMD = ['service', "rabbitmq-server", "start"]
|
START_CMD = ['service', "rabbitmq-server", "start"]
|
||||||
STOP_CMD = ['service', "rabbitmq-server", "stop"]
|
STOP_CMD = ['service', "rabbitmq-server", "stop"]
|
||||||
STATUS_CMD = ['service', "rabbitmq-server", "status"]
|
STATUS_CMD = ['service', "rabbitmq-server", "status"]
|
||||||
RESTART_CMD = ['service', "rabbitmq-server", "restart"]
|
RESTART_CMD = ['service', "rabbitmq-server", "restart"]
|
||||||
PWD_CMD = ['rabbitmqctl', 'change_password', 'guest']
|
PWD_CMD = ['rabbitmqctl', 'change_password', 'guest']
|
||||||
|
|
||||||
#default password
|
# Default password (guest)
|
||||||
RESET_BASE_PW = ''
|
RESET_BASE_PW = ''
|
||||||
|
|
||||||
#how long we wait for rabbitmq to start up before doing commands on it
|
# How long we wait for rabbitmq to start up before doing commands on it
|
||||||
WAIT_ON_TIME = settings.WAIT_ALIVE_SECS
|
WAIT_ON_TIME = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#config keys we warm up so u won't be prompted later
|
# Config keys we warm up so u won't be prompted later
|
||||||
WARMUP_PWS = ['rabbit']
|
WARMUP_PWS = ['rabbit']
|
||||||
|
|
||||||
#partial of rabbit user prompt
|
# Partial of rabbit user prompt
|
||||||
PW_USER_PROMPT = 'the rabbit user'
|
PW_USER_PROMPT = 'the rabbit user'
|
||||||
|
|
||||||
|
|
||||||
@ -96,8 +94,9 @@ class RabbitRuntime(comp.EmptyRuntime):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def status(self):
|
def status(self):
|
||||||
#this has got to be the worst status output
|
# This has got to be the worst status output.
|
||||||
#i have ever seen (its like a weird mix json+crap)
|
#
|
||||||
|
# I have ever seen (its like a weird mix json+crap)
|
||||||
run_result = sh.execute(*STATUS_CMD,
|
run_result = sh.execute(*STATUS_CMD,
|
||||||
check_exit_code=False,
|
check_exit_code=False,
|
||||||
run_as_root=True)
|
run_as_root=True)
|
||||||
@ -114,12 +113,15 @@ class RabbitRuntime(comp.EmptyRuntime):
|
|||||||
return comp.STATUS_UNKNOWN
|
return comp.STATUS_UNKNOWN
|
||||||
|
|
||||||
def _run_cmd(self, cmd, check_exit=True):
|
def _run_cmd(self, cmd, check_exit=True):
|
||||||
#this seems to fix one of the bugs with rabbit mq starting and stopping
|
# This seems to fix one of the bugs with rabbit mq starting and stopping
|
||||||
#not cool, possibly connected to the following bugs:
|
# not cool, possibly connected to the following bugs:
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
|
||||||
#
|
#
|
||||||
#rhel seems to have this bug also...
|
# See: https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
||||||
|
# See: https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
||||||
|
#
|
||||||
|
# RHEL seems to have this bug also...
|
||||||
|
#
|
||||||
|
# TODO: Move to distro dir...
|
||||||
with TemporaryFile() as f:
|
with TemporaryFile() as f:
|
||||||
return sh.execute(*cmd, run_as_root=True,
|
return sh.execute(*cmd, run_as_root=True,
|
||||||
stdout_fh=f, stderr_fh=f,
|
stdout_fh=f, stderr_fh=f,
|
||||||
|
@ -18,15 +18,12 @@ import re
|
|||||||
|
|
||||||
from devstack import component as comp
|
from devstack import component as comp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
#id
|
|
||||||
TYPE = settings.SWIFT
|
|
||||||
LOG = logging.getLogger("devstack.components.swift")
|
LOG = logging.getLogger("devstack.components.swift")
|
||||||
|
|
||||||
#swift has alot of config files!
|
# Swift has alot of config files!
|
||||||
SWIFT_CONF = 'swift.conf'
|
SWIFT_CONF = 'swift.conf'
|
||||||
PROXY_SERVER_CONF = 'proxy-server.conf'
|
PROXY_SERVER_CONF = 'proxy-server.conf'
|
||||||
ACCOUNT_SERVER_CONF = 'account-server.conf'
|
ACCOUNT_SERVER_CONF = 'account-server.conf'
|
||||||
@ -45,35 +42,35 @@ CONFIGS = [SWIFT_CONF, PROXY_SERVER_CONF, ACCOUNT_SERVER_CONF,
|
|||||||
SWIFT_RSYNC_LOC = '/etc/rsyslog.d/10-swift.conf'
|
SWIFT_RSYNC_LOC = '/etc/rsyslog.d/10-swift.conf'
|
||||||
DEF_LOOP_SIZE = 1000000
|
DEF_LOOP_SIZE = 1000000
|
||||||
|
|
||||||
#adjustments to rsync/rsyslog
|
# Adjustments to rsync/rsyslog
|
||||||
RSYNC_CONF_LOC = '/etc/default/rsync'
|
RSYNC_CONF_LOC = '/etc/default/rsync'
|
||||||
RSYNCD_CONF_LOC = '/etc/rsyncd.conf'
|
RSYNCD_CONF_LOC = '/etc/rsyncd.conf'
|
||||||
RSYNC_SERVICE_RESTART = ['service', 'rsync', 'restart']
|
RSYNC_SERVICE_RESTART = ['service', 'rsync', 'restart']
|
||||||
RSYSLOG_SERVICE_RESTART = ['service', 'rsyslog', 'restart']
|
RSYSLOG_SERVICE_RESTART = ['service', 'rsyslog', 'restart']
|
||||||
RSYNC_ON_OFF_RE = re.compile(r'^\s*RSYNC_ENABLE\s*=\s*(.*)$', re.I)
|
RSYNC_ON_OFF_RE = re.compile(r'^\s*RSYNC_ENABLE\s*=\s*(.*)$', re.I)
|
||||||
|
|
||||||
#defines our auth service type
|
# Defines our auth service type
|
||||||
AUTH_SERVICE = 'keystone'
|
AUTH_SERVICE = 'keystone'
|
||||||
|
|
||||||
#defines what type of loopback filesystem we will make
|
# Defines what type of loopback filesystem we will make
|
||||||
#xfs is preferred due to its extended attributes
|
# xfs is preferred due to its extended attributes
|
||||||
FS_TYPE = "xfs"
|
FS_TYPE = "xfs"
|
||||||
|
|
||||||
#subdirs of the git checkout
|
# Subdirs of the git checkout
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
CONFIG_DIR = 'etc'
|
CONFIG_DIR = 'etc'
|
||||||
LOG_DIR = 'logs'
|
LOG_DIR = 'logs'
|
||||||
|
|
||||||
#config keys we warm up so u won't be prompted later
|
# Config keys we warm up so u won't be prompted later
|
||||||
WARMUP_PWS = ['service_token', 'swift_hash']
|
WARMUP_PWS = ['service_token', 'swift_hash']
|
||||||
|
|
||||||
|
|
||||||
class SwiftUninstaller(comp.PythonUninstallComponent):
|
class SwiftUninstaller(comp.PythonUninstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
|
||||||
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
||||||
|
|
||||||
def pre_uninstall(self):
|
def pre_uninstall(self):
|
||||||
@ -88,12 +85,12 @@ class SwiftUninstaller(comp.PythonUninstallComponent):
|
|||||||
class SwiftInstaller(comp.PythonInstallComponent):
|
class SwiftInstaller(comp.PythonInstallComponent):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
comp.PythonInstallComponent.__init__(self, *args, **kargs)
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
||||||
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
||||||
self.startmain_file = sh.joinpths(self.bindir, SWIFT_STARTMAIN)
|
self.startmain_file = sh.joinpths(self.bin_dir, SWIFT_STARTMAIN)
|
||||||
self.makerings_file = sh.joinpths(self.bindir, SWIFT_MAKERINGS)
|
self.makerings_file = sh.joinpths(self.bin_dir, SWIFT_MAKERINGS)
|
||||||
self.fs_dev = sh.joinpths(self.datadir, DEVICE_PATH)
|
self.fs_dev = sh.joinpths(self.datadir, DEVICE_PATH)
|
||||||
self.fs_image = sh.joinpths(self.datadir, SWIFT_IMG)
|
self.fs_image = sh.joinpths(self.datadir, SWIFT_IMG)
|
||||||
self.auth_server = AUTH_SERVICE
|
self.auth_server = AUTH_SERVICE
|
||||||
@ -111,20 +108,20 @@ class SwiftInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def warm_configs(self):
|
def warm_configs(self):
|
||||||
for pw_key in WARMUP_PWS:
|
for pw_key in WARMUP_PWS:
|
||||||
self.cfg.get("passwords", pw_key)
|
self.pw_gen.get_password(pw_key)
|
||||||
|
|
||||||
def _get_param_map(self, config_fn):
|
def _get_param_map(self, config_fn):
|
||||||
return {
|
return {
|
||||||
'USER': self.cfg.getdefaulted('swift', 'swift_user', sh.getuser()),
|
'USER': self.cfg.getdefaulted('swift', 'swift_user', sh.getuser()),
|
||||||
'GROUP': self.cfg.getdefaulted('swift', 'swift_group', sh.getgroupname()),
|
'GROUP': self.cfg.getdefaulted('swift', 'swift_group', sh.getgroupname()),
|
||||||
'SWIFT_DATA_LOCATION': self.datadir,
|
'SWIFT_DATA_LOCATION': self.datadir,
|
||||||
'SWIFT_CONFIG_LOCATION': self.cfgdir,
|
'SWIFT_CONFIG_LOCATION': self.cfg_dir,
|
||||||
'SERVICE_TOKEN': self.cfg.get('passwords', 'service_token'),
|
'SERVICE_TOKEN': self.cfg.get('passwords', 'service_token'),
|
||||||
'AUTH_SERVER': self.auth_server,
|
'AUTH_SERVER': self.auth_server,
|
||||||
'SWIFT_HASH': self.cfg.get('passwords', 'swift_hash'),
|
'SWIFT_HASH': self.cfg.get('passwords', 'swift_hash'),
|
||||||
'SWIFT_LOGDIR': self.logdir,
|
'SWIFT_LOGDIR': self.logdir,
|
||||||
'SWIFT_PARTITION_POWER_SIZE': self.cfg.getdefaulted('swift', 'partition_power_size', '9'),
|
'SWIFT_PARTITION_POWER_SIZE': self.cfg.getdefaulted('swift', 'partition_power_size', '9'),
|
||||||
#leave these alone, will be adjusted later
|
# Note: leave these alone, will be adjusted later
|
||||||
'NODE_PATH': '%NODE_PATH%',
|
'NODE_PATH': '%NODE_PATH%',
|
||||||
'BIND_PORT': '%BIND_PORT%',
|
'BIND_PORT': '%BIND_PORT%',
|
||||||
'LOG_FACILITY': '%LOG_FACILITY%',
|
'LOG_FACILITY': '%LOG_FACILITY%',
|
||||||
@ -145,8 +142,8 @@ class SwiftInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _create_node_config(self, node_number, port):
|
def _create_node_config(self, node_number, port):
|
||||||
for t in ['object', 'container', 'account']:
|
for t in ['object', 'container', 'account']:
|
||||||
src_fn = sh.joinpths(self.cfgdir, '%s-server.conf' % t)
|
src_fn = sh.joinpths(self.cfg_dir, '%s-server.conf' % t)
|
||||||
tgt_fn = sh.joinpths(self.cfgdir, '%s-server/%d.conf' % (t, node_number))
|
tgt_fn = sh.joinpths(self.cfg_dir, '%s-server/%d.conf' % (t, node_number))
|
||||||
adjustments = {
|
adjustments = {
|
||||||
'%NODE_PATH%': sh.joinpths(self.datadir, str(node_number)),
|
'%NODE_PATH%': sh.joinpths(self.datadir, str(node_number)),
|
||||||
'%BIND_PORT%': str(port),
|
'%BIND_PORT%': str(port),
|
||||||
@ -157,7 +154,7 @@ class SwiftInstaller(comp.PythonInstallComponent):
|
|||||||
|
|
||||||
def _delete_templates(self):
|
def _delete_templates(self):
|
||||||
for t in ['object', 'container', 'account']:
|
for t in ['object', 'container', 'account']:
|
||||||
sh.unlink(sh.joinpths(self.cfgdir, '%s-server.conf' % t))
|
sh.unlink(sh.joinpths(self.cfg_dir, '%s-server.conf' % t))
|
||||||
|
|
||||||
def _create_nodes(self):
|
def _create_nodes(self):
|
||||||
for i in range(1, 5):
|
for i in range(1, 5):
|
||||||
@ -170,20 +167,20 @@ class SwiftInstaller(comp.PythonInstallComponent):
|
|||||||
self._delete_templates()
|
self._delete_templates()
|
||||||
|
|
||||||
def _turn_on_rsync(self):
|
def _turn_on_rsync(self):
|
||||||
sh.symlink(sh.joinpths(self.cfgdir, RSYNC_CONF), RSYNCD_CONF_LOC)
|
sh.symlink(sh.joinpths(self.cfg_dir, RSYNC_CONF), RSYNCD_CONF_LOC)
|
||||||
self.tracewriter.symlink_made(RSYNCD_CONF_LOC)
|
self.tracewriter.symlink_made(RSYNCD_CONF_LOC)
|
||||||
sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=true', True)
|
sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=true', True)
|
||||||
|
|
||||||
def _create_log_dirs(self):
|
def _create_log_dirs(self):
|
||||||
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.logdir, 'hourly')))
|
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.logdir, 'hourly')))
|
||||||
sh.symlink(sh.joinpths(self.cfgdir, SYSLOG_CONF), SWIFT_RSYNC_LOC)
|
sh.symlink(sh.joinpths(self.cfg_dir, SYSLOG_CONF), SWIFT_RSYNC_LOC)
|
||||||
self.tracewriter.symlink_made(SWIFT_RSYNC_LOC)
|
self.tracewriter.symlink_made(SWIFT_RSYNC_LOC)
|
||||||
|
|
||||||
def _setup_binaries(self):
|
def _setup_binaries(self):
|
||||||
sh.move(sh.joinpths(self.cfgdir, SWIFT_MAKERINGS), self.makerings_file)
|
sh.move(sh.joinpths(self.cfg_dir, SWIFT_MAKERINGS), self.makerings_file)
|
||||||
sh.chmod(self.makerings_file, 0777)
|
sh.chmod(self.makerings_file, 0777)
|
||||||
self.tracewriter.file_touched(self.makerings_file)
|
self.tracewriter.file_touched(self.makerings_file)
|
||||||
sh.move(sh.joinpths(self.cfgdir, SWIFT_STARTMAIN), self.startmain_file)
|
sh.move(sh.joinpths(self.cfg_dir, SWIFT_STARTMAIN), self.startmain_file)
|
||||||
sh.chmod(self.startmain_file, 0777)
|
sh.chmod(self.startmain_file, 0777)
|
||||||
self.tracewriter.file_touched(self.startmain_file)
|
self.tracewriter.file_touched(self.startmain_file)
|
||||||
|
|
||||||
@ -202,21 +199,21 @@ class SwiftInstaller(comp.PythonInstallComponent):
|
|||||||
class SwiftRuntime(comp.PythonRuntime):
|
class SwiftRuntime(comp.PythonRuntime):
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
comp.PythonRuntime.__init__(self, *args, **kargs)
|
comp.PythonRuntime.__init__(self, *args, **kargs)
|
||||||
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
|
||||||
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
|
||||||
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
|
||||||
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True)
|
sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True)
|
||||||
sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True)
|
sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True)
|
||||||
swift_start_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'start']
|
swift_start_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'start']
|
||||||
sh.execute(*swift_start_cmd, run_as_root=True)
|
sh.execute(*swift_start_cmd, run_as_root=True)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
swift_stop_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'stop']
|
swift_stop_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'stop']
|
||||||
sh.execute(*swift_stop_cmd, run_as_root=True)
|
sh.execute(*swift_stop_cmd, run_as_root=True)
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
swift_restart_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'restart']
|
swift_restart_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'restart']
|
||||||
sh.execute(*swift_restart_cmd, run_as_root=True)
|
sh.execute(*swift_restart_cmd, run_as_root=True)
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import os
|
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -25,31 +24,28 @@ import yaml
|
|||||||
from devstack import importer
|
from devstack import importer
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
from devstack import settings
|
||||||
from devstack import utils
|
from devstack import shell as sh
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger('devstack.distro')
|
LOG = logging.getLogger('devstack.distro')
|
||||||
|
|
||||||
DISTRO_CONF_DIR = os.path.join(settings.STACK_CONFIG_DIR, 'distros')
|
|
||||||
|
|
||||||
|
|
||||||
class Distro(object):
|
class Distro(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_all(cls, path=DISTRO_CONF_DIR):
|
def load_all(cls, path=settings.STACK_DISTRO_DIR):
|
||||||
"""Returns a list of the known distros."""
|
"""Returns a list of the known distros."""
|
||||||
results = []
|
results = []
|
||||||
input_files = glob.glob(os.path.join(DISTRO_CONF_DIR, '*.yaml'))
|
input_files = glob.glob(sh.joinpths(path, '*.yaml'))
|
||||||
if not input_files:
|
if not input_files:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'Did not find any distro definition files in %s' %
|
'Did not find any distro definition files in %s' %
|
||||||
DISTRO_CONF_DIR)
|
path)
|
||||||
for filename in input_files:
|
for filename in input_files:
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
data = yaml.load(f)
|
data = yaml.load(f)
|
||||||
results.append(cls(**data))
|
results.append(cls(**data))
|
||||||
except Exception as err:
|
except (IOError, yaml.YAMLError) as err:
|
||||||
LOG.warning('Could not load distro definition from %s: %s',
|
LOG.warning('Could not load distro definition from %s: %s',
|
||||||
filename, err)
|
filename, err)
|
||||||
return results
|
return results
|
||||||
@ -64,7 +60,7 @@ class Distro(object):
|
|||||||
LOG.debug('Looking for distro data for %s (%s)', plt, distname)
|
LOG.debug('Looking for distro data for %s (%s)', plt, distname)
|
||||||
for p in cls.load_all():
|
for p in cls.load_all():
|
||||||
if p.supports_distro(plt):
|
if p.supports_distro(plt):
|
||||||
LOG.info('Using distro "%s" for "%s"', p.name, plt)
|
LOG.info('Using distro "%s" for platform "%s"', p.name, plt)
|
||||||
return p
|
return p
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
@ -73,51 +69,60 @@ class Distro(object):
|
|||||||
|
|
||||||
def __init__(self, name, distro_pattern, packager_name, commands, components):
|
def __init__(self, name, distro_pattern, packager_name, commands, components):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.distro_pattern = re.compile(distro_pattern, re.IGNORECASE)
|
self._distro_pattern = re.compile(distro_pattern, re.IGNORECASE)
|
||||||
self.packager_name = packager_name
|
self._packager_name = packager_name
|
||||||
self.commands = commands
|
self._commands = commands
|
||||||
self.components = components
|
self._components = components
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "\"%s\" using packager \"%s\"" % (self.name, self._packager_name)
|
||||||
|
|
||||||
|
def get_command(self, key, *more_keys, **kargs):
|
||||||
|
""" Gets a end object for a given set of keys """
|
||||||
|
root = self._commands
|
||||||
|
acutal_keys = [key] + list(more_keys)
|
||||||
|
run_over_keys = acutal_keys[0:-1]
|
||||||
|
end_key = acutal_keys[-1]
|
||||||
|
quiet = kargs.get('quiet', False)
|
||||||
|
for k in run_over_keys:
|
||||||
|
if quiet:
|
||||||
|
root = root.get(k)
|
||||||
|
if root is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
root = root[k]
|
||||||
|
if not quiet:
|
||||||
|
return root[end_key]
|
||||||
|
else:
|
||||||
|
return root.get(end_key)
|
||||||
|
|
||||||
|
def known_component(self, name):
|
||||||
|
return name in self._components
|
||||||
|
|
||||||
def supports_distro(self, distro_name):
|
def supports_distro(self, distro_name):
|
||||||
"""Does this distro support the named Linux distro?
|
"""Does this distro support the named Linux distro?
|
||||||
|
|
||||||
:param distro_name: Return value from platform.linux_distribution().
|
:param distro_name: Return value from platform.linux_distribution().
|
||||||
"""
|
"""
|
||||||
return bool(self.distro_pattern.search(distro_name))
|
return bool(self._distro_pattern.search(distro_name))
|
||||||
|
|
||||||
def get_packager_factory(self):
|
def get_packager_factory(self):
|
||||||
"""Return a factory for a package manager."""
|
"""Return a factory for a package manager."""
|
||||||
return importer.import_entry_point(self.packager_name)
|
return importer.import_entry_point(self._packager_name)
|
||||||
|
|
||||||
def get_component_action_class(self, name, action):
|
def extract_component(self, name, action):
|
||||||
"""Return the class to use for doing the action w/the component."""
|
"""Return the class + component info to use for doing the action w/the component."""
|
||||||
try:
|
try:
|
||||||
entry_point = self.components[name][action]
|
# Use a copy instead of the original
|
||||||
|
component_info = dict(self._components[name])
|
||||||
|
entry_point = component_info[action]
|
||||||
|
cls = importer.import_entry_point(entry_point)
|
||||||
|
# Knock all action class info (and any other keys)
|
||||||
|
key_deletions = [action] + settings.ACTIONS
|
||||||
|
for k in key_deletions:
|
||||||
|
if k in component_info:
|
||||||
|
del component_info[k]
|
||||||
|
return (cls, component_info)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise RuntimeError('No class configured to %s %s on %s' %
|
raise RuntimeError('No class configured to %s %s on %s' %
|
||||||
(action, name, self.name))
|
(action, name, self.name))
|
||||||
return importer.import_entry_point(entry_point)
|
|
||||||
|
|
||||||
def resolve_component_dependencies(self, components):
|
|
||||||
"""Returns list of all components needed for the named components."""
|
|
||||||
all_components = {}
|
|
||||||
active_names = [(c, None) for c in components]
|
|
||||||
while active_names:
|
|
||||||
component, parent = active_names.pop()
|
|
||||||
try:
|
|
||||||
component_details = self.components[component]
|
|
||||||
except KeyError:
|
|
||||||
if parent:
|
|
||||||
raise RuntimeError(
|
|
||||||
'Could not find details about component %r, a dependency of %s, for %s' %
|
|
||||||
(component, parent, self.name))
|
|
||||||
else:
|
|
||||||
raise RuntimeError(
|
|
||||||
'Could not find details about component %r for %s' %
|
|
||||||
(component, self.name))
|
|
||||||
deps = set(component_details.get('dependencies', []))
|
|
||||||
all_components[component] = deps
|
|
||||||
for d in deps:
|
|
||||||
if d not in all_components and d not in active_names:
|
|
||||||
active_names.append((d, component))
|
|
||||||
return all_components
|
|
||||||
|
@ -1,10 +1,31 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
||||||
|
# Copyright (C) 2012 Dreamhost Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
"""Platform-specific logic for Ubunutu Oneiric components.
|
"""Platform-specific logic for Ubunutu Oneiric components.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
from devstack.components import db
|
from devstack.components import db
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
from devstack.packaging import apt
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -23,3 +44,35 @@ class OneiricDBInstaller(db.DBInstaller):
|
|||||||
fc = utils.joinlinesep(*new_lines)
|
fc = utils.joinlinesep(*new_lines)
|
||||||
with sh.Rooted(True):
|
with sh.Rooted(True):
|
||||||
sh.write_file('/etc/mysql/my.cnf', fc)
|
sh.write_file('/etc/mysql/my.cnf', fc)
|
||||||
|
|
||||||
|
|
||||||
|
class OneiricAptPackager(apt.AptPackager):
|
||||||
|
|
||||||
|
def _pkg_remove_special(self, name, pkginfo):
|
||||||
|
if name == 'rabbitmq-server':
|
||||||
|
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
||||||
|
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
||||||
|
LOG.info("Handling special remove of %s." % (name))
|
||||||
|
pkg_full = self._format_pkg(name, pkginfo.get("version"))
|
||||||
|
cmd = apt.APT_GET + apt.APT_REMOVE + [pkg_full]
|
||||||
|
self._execute_apt(cmd)
|
||||||
|
#probably useful to do this
|
||||||
|
time.sleep(1)
|
||||||
|
#purge
|
||||||
|
cmd = apt.APT_GET + apt.APT_PURGE + [pkg_full]
|
||||||
|
self._execute_apt(cmd)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _pkg_install_special(self, name, pkginfo):
|
||||||
|
if name == 'rabbitmq-server':
|
||||||
|
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
||||||
|
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
||||||
|
LOG.info("Handling special install of %s." % (name))
|
||||||
|
#this seems to be a temporary fix for that bug
|
||||||
|
with tempfile.TemporaryFile() as f:
|
||||||
|
pkg_full = self._format_pkg(name, pkginfo.get("version"))
|
||||||
|
cmd = apt.APT_GET + apt.APT_INSTALL + [pkg_full]
|
||||||
|
self._execute_apt(cmd, stdout_fh=f, stderr_fh=f)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
71
devstack/distros/rhel6.py
Normal file
71
devstack/distros/rhel6.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
||||||
|
# Copyright (C) 2012 Dreamhost Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""Platform-specific logic for RHEL6 components.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from devstack import log as logging
|
||||||
|
from devstack import shell as sh
|
||||||
|
from devstack import utils
|
||||||
|
|
||||||
|
from devstack.components import db
|
||||||
|
from devstack.components import horizon
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
SOCKET_CONF = "/etc/httpd/conf.d/wsgi-socket-prefix.conf"
|
||||||
|
HTTPD_CONF = '/etc/httpd/conf/httpd.conf'
|
||||||
|
|
||||||
|
|
||||||
|
class Rhel6DBInstaller(db.DBInstaller):
|
||||||
|
|
||||||
|
def _configure_db_confs(self):
|
||||||
|
dbtype = self.cfg.get("db", "type")
|
||||||
|
if dbtype == 'mysql':
|
||||||
|
LOG.info("Fixing up mysql configs.")
|
||||||
|
fc = sh.load_file('/etc/my.cnf')
|
||||||
|
lines = fc.splitlines()
|
||||||
|
new_lines = list()
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith('skip-grant-tables'):
|
||||||
|
line = '#' + line
|
||||||
|
new_lines.append(line)
|
||||||
|
fc = utils.joinlinesep(*new_lines)
|
||||||
|
with sh.Rooted(True):
|
||||||
|
sh.write_file('/etc/my.cnf', fc)
|
||||||
|
|
||||||
|
|
||||||
|
class Rhel6HorizonInstaller(horizon.HorizonInstaller):
|
||||||
|
|
||||||
|
def _config_fixups(self):
|
||||||
|
(user, group) = self._get_apache_user_group()
|
||||||
|
self.tracewriter.file_touched(SOCKET_CONF)
|
||||||
|
# Not recorded since we aren't really creating this
|
||||||
|
LOG.info("Fixing up %s and %s files" % (SOCKET_CONF, HTTPD_CONF))
|
||||||
|
with sh.Rooted(True):
|
||||||
|
# Fix the socket prefix to someplace we can use
|
||||||
|
fc = "WSGISocketPrefix %s" % (sh.joinpths(self.log_dir, "wsgi-socket"))
|
||||||
|
sh.write_file(SOCKET_CONF, fc)
|
||||||
|
# Now adjust the run user and group (of httpd.conf)
|
||||||
|
new_lines = list()
|
||||||
|
for line in sh.load_file(HTTPD_CONF).splitlines():
|
||||||
|
if line.startswith("User "):
|
||||||
|
line = "User %s" % (user)
|
||||||
|
if line.startswith("Group "):
|
||||||
|
line = "Group %s" % (group)
|
||||||
|
new_lines.append(line)
|
||||||
|
sh.write_file(HTTPD_CONF, utils.joinlinesep(*new_lines))
|
@ -51,7 +51,6 @@ def _gitdownload(storewhere, uri, branch=None):
|
|||||||
|
|
||||||
|
|
||||||
def download(storewhere, uri, branch=None):
|
def download(storewhere, uri, branch=None):
|
||||||
#figure out which type
|
|
||||||
up = urlparse(uri)
|
up = urlparse(uri)
|
||||||
if up and up.scheme.lower() == "git" or GIT_EXT_REG.match(up.path):
|
if up and up.scheme.lower() == "git" or GIT_EXT_REG.match(up.path):
|
||||||
return _gitdownload(storewhere, uri, branch)
|
return _gitdownload(storewhere, uri, branch)
|
||||||
|
@ -26,9 +26,9 @@ def get():
|
|||||||
|
|
||||||
|
|
||||||
def set(key, value):
|
def set(key, value):
|
||||||
#this is really screwy, python is really odd in this area
|
# This is really screwy, python is really odd in this area
|
||||||
#from http://docs.python.org/library/os.html
|
# See: from http://docs.python.org/library/os.html
|
||||||
#Calling putenv() directly does not change os.environ, so it's better to modify os.environ.
|
# Calling putenv() directly does not change os.environ, so it's better to modify os.environ.
|
||||||
if key is not None:
|
if key is not None:
|
||||||
LOG.audit("Setting environment key [%s] to value [%s]" % (key, value))
|
LOG.audit("Setting environment key [%s] to value [%s]" % (key, value))
|
||||||
os.environ[str(key)] = str(value)
|
os.environ[str(key)] = str(value)
|
||||||
@ -43,5 +43,5 @@ def get_key(key, default_value=None):
|
|||||||
LOG.debug("Could not find anything in environment variable [%s]" % (key))
|
LOG.debug("Could not find anything in environment variable [%s]" % (key))
|
||||||
value = default_value
|
value = default_value
|
||||||
else:
|
else:
|
||||||
LOG.debug("Found [%s] in environment variable [%s]" % (value, key))
|
LOG.audit("Found [%s] in environment variable [%s]" % (value, key))
|
||||||
return value
|
return value
|
||||||
|
@ -28,13 +28,13 @@ from devstack.components import keystone
|
|||||||
|
|
||||||
LOG = logging.getLogger('devstack.env_rc')
|
LOG = logging.getLogger('devstack.env_rc')
|
||||||
|
|
||||||
#general extraction cfg keys+section
|
# General extraction cfg keys + sections
|
||||||
CFG_MAKE = {
|
CFG_MAKE = {
|
||||||
'FLAT_INTERFACE': ('nova', 'flat_interface'),
|
'FLAT_INTERFACE': ('nova', 'flat_interface'),
|
||||||
'HOST_IP': ('host', 'ip'),
|
'HOST_IP': ('host', 'ip'),
|
||||||
}
|
}
|
||||||
|
|
||||||
#general password keys
|
# General password keys
|
||||||
PASSWORDS_MAKES = {
|
PASSWORDS_MAKES = {
|
||||||
'ADMIN_PASSWORD': 'horizon_keystone_admin',
|
'ADMIN_PASSWORD': 'horizon_keystone_admin',
|
||||||
'SERVICE_PASSWORD': 'service_password',
|
'SERVICE_PASSWORD': 'service_password',
|
||||||
@ -43,17 +43,17 @@ PASSWORDS_MAKES = {
|
|||||||
'MYSQL_PASSWORD': 'sql',
|
'MYSQL_PASSWORD': 'sql',
|
||||||
}
|
}
|
||||||
|
|
||||||
#install root
|
# Install root output name and env variable name
|
||||||
INSTALL_ROOT = 'INSTALL_ROOT'
|
INSTALL_ROOT = 'INSTALL_ROOT'
|
||||||
|
|
||||||
#default ports
|
# Default ports
|
||||||
EC2_PORT = 8773
|
EC2_PORT = 8773
|
||||||
S3_PORT = 3333
|
S3_PORT = 3333
|
||||||
|
|
||||||
#how we know if a line is an export or if it isn't (simpe edition)
|
# How we know if a line is an export or if it isn't (simpe edition)
|
||||||
EXP_PAT = re.compile("^\s*export\s+(.*?)=(.*?)$", re.IGNORECASE)
|
EXP_PAT = re.compile("^\s*export\s+(.*?)=(.*?)$", re.IGNORECASE)
|
||||||
|
|
||||||
#how we unquote a string (simple edition)
|
# How we unquote a string (simple edition)
|
||||||
QUOTED_PAT = re.compile(r"^\s*[\"](.*)[\"]\s*$")
|
QUOTED_PAT = re.compile(r"^\s*[\"](.*)[\"]\s*$")
|
||||||
|
|
||||||
|
|
||||||
@ -182,8 +182,8 @@ class RcWriter(object):
|
|||||||
to_set['OS_PASSWORD'] = key_params['ADMIN_PASSWORD']
|
to_set['OS_PASSWORD'] = key_params['ADMIN_PASSWORD']
|
||||||
to_set['OS_TENANT_NAME'] = key_params['DEMO_TENANT_NAME']
|
to_set['OS_TENANT_NAME'] = key_params['DEMO_TENANT_NAME']
|
||||||
to_set['OS_USERNAME'] = key_params['DEMO_USER_NAME']
|
to_set['OS_USERNAME'] = key_params['DEMO_USER_NAME']
|
||||||
# this seems named weirdly the OS_AUTH_URL is the keystone SERVICE_ENDPOINT endpoint
|
# This seems named weirdly the OS_AUTH_URL is the keystone SERVICE_ENDPOINT endpoint
|
||||||
# todo: describe more why this is the case
|
# Todo: describe more why this is the case...
|
||||||
to_set['OS_AUTH_URL'] = key_params['SERVICE_ENDPOINT']
|
to_set['OS_AUTH_URL'] = key_params['SERVICE_ENDPOINT']
|
||||||
return to_set
|
return to_set
|
||||||
|
|
||||||
@ -246,11 +246,23 @@ class RcReader(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _is_comment(self, line):
|
||||||
|
if line.lstrip().startswith("#"):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def extract(self, fn):
|
def extract(self, fn):
|
||||||
extracted_vars = dict()
|
extracted_vars = dict()
|
||||||
contents = sh.load_file(fn)
|
contents = ''
|
||||||
|
LOG.audit("Loading rc file [%s]" % (fn))
|
||||||
|
try:
|
||||||
|
with open(fn, 'r') as fh:
|
||||||
|
contents = fh.read()
|
||||||
|
except IOError as e:
|
||||||
|
LOG.warn("Failed extracting rc file [%s] due to [%s]" % (fn, e))
|
||||||
|
return extracted_vars
|
||||||
for line in contents.splitlines():
|
for line in contents.splitlines():
|
||||||
if line.lstrip().startswith("#"):
|
if self._is_comment(line):
|
||||||
continue
|
continue
|
||||||
m = EXP_PAT.search(line)
|
m = EXP_PAT.search(line)
|
||||||
if m:
|
if m:
|
||||||
|
@ -236,16 +236,16 @@ class ImageCreationService:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
# prepare the request
|
# Prepare the request
|
||||||
request = urllib2.Request(keystone_token_url)
|
request = urllib2.Request(keystone_token_url)
|
||||||
|
|
||||||
# post body
|
# Post body
|
||||||
request.add_data(data)
|
request.add_data(data)
|
||||||
|
|
||||||
# content type
|
# Content type
|
||||||
request.add_header('Content-Type', 'application/json')
|
request.add_header('Content-Type', 'application/json')
|
||||||
|
|
||||||
# make the request
|
# Make the request
|
||||||
LOG.info("Getting your token from url [%s], please wait..." % (keystone_token_url))
|
LOG.info("Getting your token from url [%s], please wait..." % (keystone_token_url))
|
||||||
LOG.debug("With post json data %s" % (data))
|
LOG.debug("With post json data %s" % (data))
|
||||||
response = urllib2.urlopen(request)
|
response = urllib2.urlopen(request)
|
||||||
@ -258,7 +258,7 @@ class ImageCreationService:
|
|||||||
msg = "Response from url [%s] did not match expected json format." % (keystone_token_url)
|
msg = "Response from url [%s] did not match expected json format." % (keystone_token_url)
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
#basic checks passed, extract it!
|
# Basic checks passed, extract it!
|
||||||
tok = token['access']['token']['id']
|
tok = token['access']['token']['id']
|
||||||
LOG.debug("Got token %s" % (tok))
|
LOG.debug("Got token %s" % (tok))
|
||||||
return tok
|
return tok
|
||||||
@ -268,7 +268,7 @@ class ImageCreationService:
|
|||||||
token = None
|
token = None
|
||||||
LOG.info("Setting up any specified images in glance.")
|
LOG.info("Setting up any specified images in glance.")
|
||||||
|
|
||||||
#extract them from the config
|
# Extract the urls from the config
|
||||||
try:
|
try:
|
||||||
flat_urls = self.cfg.getdefaulted('img', 'image_urls', [])
|
flat_urls = self.cfg.getdefaulted('img', 'image_urls', [])
|
||||||
expanded_urls = [x.strip() for x in flat_urls.split(',')]
|
expanded_urls = [x.strip() for x in flat_urls.split(',')]
|
||||||
@ -278,7 +278,7 @@ class ImageCreationService:
|
|||||||
except(ConfigParser.Error):
|
except(ConfigParser.Error):
|
||||||
LOG.warn("No image configuration keys found, skipping glance image install!")
|
LOG.warn("No image configuration keys found, skipping glance image install!")
|
||||||
|
|
||||||
#install them in glance
|
# Install them in glance
|
||||||
am_installed = 0
|
am_installed = 0
|
||||||
if urls:
|
if urls:
|
||||||
LOG.info("Attempting to download & extract and upload (%s) images." % (", ".join(urls)))
|
LOG.info("Attempting to download & extract and upload (%s) images." % (", ".join(urls)))
|
||||||
|
@ -1,13 +1,36 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
||||||
|
# Copyright (C) 2012 Dreamhost Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
def import_entry_point(fullname):
|
def partition(fullname):
|
||||||
"""Given a name import the class and return it.
|
"""
|
||||||
|
|
||||||
The name should be in dotted.path:ClassName syntax.
|
The name should be in dotted.path:ClassName syntax.
|
||||||
"""
|
"""
|
||||||
if ':' not in fullname:
|
if ':' not in fullname:
|
||||||
raise ValueError('Invalid entry point specifier %r' % fullname)
|
raise ValueError('Invalid entry point specifier %r' % fullname)
|
||||||
module_name, ignore, classname = fullname.partition(':')
|
(module_name, _, classname) = fullname.partition(':')
|
||||||
|
return (module_name, classname)
|
||||||
|
|
||||||
|
|
||||||
|
def import_entry_point(fullname):
|
||||||
|
"""
|
||||||
|
Given a name import the class and return it.
|
||||||
|
"""
|
||||||
|
(module_name, classname) = partition(fullname)
|
||||||
try:
|
try:
|
||||||
module = __import__(module_name)
|
module = __import__(module_name)
|
||||||
for submodule in module_name.split('.')[1:]:
|
for submodule in module_name.split('.')[1:]:
|
||||||
|
@ -22,7 +22,7 @@ from devstack import utils
|
|||||||
|
|
||||||
LOG = logging.getLogger('devstack.libvirt')
|
LOG = logging.getLogger('devstack.libvirt')
|
||||||
|
|
||||||
#http://libvirt.org/uri.html
|
# See: http://libvirt.org/uri.html
|
||||||
LIBVIRT_PROTOCOL_MAP = {
|
LIBVIRT_PROTOCOL_MAP = {
|
||||||
'qemu': "qemu:///system",
|
'qemu': "qemu:///system",
|
||||||
'kvm': "qemu:///system",
|
'kvm': "qemu:///system",
|
||||||
@ -32,35 +32,28 @@ LIBVIRT_PROTOCOL_MAP = {
|
|||||||
}
|
}
|
||||||
VIRT_LIB = 'libvirt'
|
VIRT_LIB = 'libvirt'
|
||||||
|
|
||||||
#distros name the libvirt service differently :-(
|
# How libvirt is restarted
|
||||||
SV_NAME_MAP = {
|
|
||||||
settings.RHEL6: 'libvirtd',
|
|
||||||
settings.FEDORA16: 'libvirtd',
|
|
||||||
settings.UBUNTU11: 'libvirt-bin',
|
|
||||||
}
|
|
||||||
|
|
||||||
#how libvirt is restarted
|
|
||||||
LIBVIRT_RESTART_CMD = ['service', '%SERVICE%', 'restart']
|
LIBVIRT_RESTART_CMD = ['service', '%SERVICE%', 'restart']
|
||||||
|
|
||||||
#how we check its status
|
# How we check its status
|
||||||
LIBVIRT_STATUS_CMD = ['service', '%SERVICE%', 'status']
|
LIBVIRT_STATUS_CMD = ['service', '%SERVICE%', 'status']
|
||||||
|
|
||||||
#this is just used to check that libvirt will work with
|
# This is just used to check that libvirt will work with
|
||||||
#a given protocol, may not be ideal but does seem to crap
|
# a given protocol, may not be ideal but does seem to crap
|
||||||
#out if it won't work, so thats good
|
# out if it won't work, so thats good...
|
||||||
VIRSH_SANITY_CMD = ['virsh', '-c', '%VIRT_PROTOCOL%', 'uri']
|
VIRSH_SANITY_CMD = ['virsh', '-c', '%VIRT_PROTOCOL%', 'uri']
|
||||||
|
|
||||||
#status is either dead or alive!
|
# Status is either dead or alive!
|
||||||
_DEAD = 'DEAD'
|
_DEAD = 'DEAD'
|
||||||
_ALIVE = 'ALIVE'
|
_ALIVE = 'ALIVE'
|
||||||
|
|
||||||
#alive wait time, just a sleep we put into so that the service can start up
|
# Alive wait time, just a sleep we put into so that the service can start up
|
||||||
WAIT_ALIVE_TIME = settings.WAIT_ALIVE_SECS
|
WAIT_ALIVE_TIME = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
|
|
||||||
def _get_virt_lib():
|
def _get_virt_lib():
|
||||||
#late import so that we don't always need this library to be active
|
# Late import so that we don't always need this library to be active
|
||||||
#ie if u aren't using libvirt in the first place
|
# ie if u aren't using libvirt in the first place...
|
||||||
return utils.import_module(VIRT_LIB)
|
return utils.import_module(VIRT_LIB)
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +64,7 @@ def _status(distro):
|
|||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
})
|
})
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['SERVICE'] = SV_NAME_MAP[distro]
|
mp['SERVICE'] = distro.get_command('libvirt-daemon')
|
||||||
result = utils.execute_template(*cmds,
|
result = utils.execute_template(*cmds,
|
||||||
check_exit_code=False,
|
check_exit_code=False,
|
||||||
params=mp)
|
params=mp)
|
||||||
@ -104,7 +97,7 @@ def restart(distro):
|
|||||||
'run_as_root': True,
|
'run_as_root': True,
|
||||||
})
|
})
|
||||||
mp = dict()
|
mp = dict()
|
||||||
mp['SERVICE'] = SV_NAME_MAP[distro]
|
mp['SERVICE'] = distro.get_command('libvirt-daemon')
|
||||||
utils.execute_template(*cmds, params=mp)
|
utils.execute_template(*cmds, params=mp)
|
||||||
LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME))
|
LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME))
|
||||||
sh.sleep(WAIT_ALIVE_TIME)
|
sh.sleep(WAIT_ALIVE_TIME)
|
||||||
@ -117,7 +110,7 @@ def virt_ok(virt_type, distro):
|
|||||||
try:
|
try:
|
||||||
restart(distro)
|
restart(distro)
|
||||||
except excp.ProcessExecutionError, e:
|
except excp.ProcessExecutionError, e:
|
||||||
LOG.warn("Could not restart libvirt on distro [%s] due to [%s]" % (distro, e.message))
|
LOG.warn("Could not restart libvirt due to [%s]" % (e))
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
cmds = list()
|
cmds = list()
|
||||||
@ -148,7 +141,7 @@ def clear_libvirt_domains(distro, virt_type, inst_prefix):
|
|||||||
try:
|
try:
|
||||||
restart(distro)
|
restart(distro)
|
||||||
except excp.ProcessExecutionError, e:
|
except excp.ProcessExecutionError, e:
|
||||||
LOG.warn("Could not restart libvirt on distro [%s] due to [%s]" % (distro, e.message))
|
LOG.warn("Could not restart libvirt due to [%s]" % (e))
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
conn = libvirt.open(virt_protocol)
|
conn = libvirt.open(virt_protocol)
|
||||||
|
@ -24,7 +24,7 @@ import pprint
|
|||||||
from logging.handlers import SysLogHandler
|
from logging.handlers import SysLogHandler
|
||||||
from logging.handlers import WatchedFileHandler
|
from logging.handlers import WatchedFileHandler
|
||||||
|
|
||||||
# a list of things we want to replicate from logging levels
|
# Alist of things we want to replicate from logging levels
|
||||||
CRITICAL = logging.CRITICAL
|
CRITICAL = logging.CRITICAL
|
||||||
FATAL = logging.FATAL
|
FATAL = logging.FATAL
|
||||||
ERROR = logging.ERROR
|
ERROR = logging.ERROR
|
||||||
@ -34,13 +34,13 @@ INFO = logging.INFO
|
|||||||
DEBUG = logging.DEBUG
|
DEBUG = logging.DEBUG
|
||||||
NOTSET = logging.NOTSET
|
NOTSET = logging.NOTSET
|
||||||
|
|
||||||
# our new audit level
|
# Our new audit level
|
||||||
# http://docs.python.org/howto/logging.html#logging-levels
|
# See: http://docs.python.org/howto/logging.html#logging-levels
|
||||||
logging.AUDIT = logging.DEBUG + 1
|
logging.AUDIT = logging.DEBUG + 1
|
||||||
logging.addLevelName(logging.AUDIT, 'AUDIT')
|
logging.addLevelName(logging.AUDIT, 'AUDIT')
|
||||||
AUDIT = logging.AUDIT
|
AUDIT = logging.AUDIT
|
||||||
|
|
||||||
# methods
|
# Methods
|
||||||
debug = logging.debug
|
debug = logging.debug
|
||||||
info = logging.info
|
info = logging.info
|
||||||
warning = logging.warning
|
warning = logging.warning
|
||||||
@ -50,11 +50,11 @@ exception = logging.exception
|
|||||||
critical = logging.critical
|
critical = logging.critical
|
||||||
log = logging.log
|
log = logging.log
|
||||||
|
|
||||||
# classes
|
# Classes
|
||||||
root = logging.root
|
root = logging.root
|
||||||
Formatter = logging.Formatter
|
Formatter = logging.Formatter
|
||||||
|
|
||||||
# handlers
|
# Handlers
|
||||||
StreamHandler = logging.StreamHandler
|
StreamHandler = logging.StreamHandler
|
||||||
WatchedFileHandler = WatchedFileHandler
|
WatchedFileHandler = WatchedFileHandler
|
||||||
SysLogHandler = SysLogHandler
|
SysLogHandler = SysLogHandler
|
||||||
|
@ -35,10 +35,8 @@ def parse():
|
|||||||
version_str = "%prog v" + version.version_string()
|
version_str = "%prog v" + version.version_string()
|
||||||
help_formatter = IndentedHelpFormatter(width=HELP_WIDTH)
|
help_formatter = IndentedHelpFormatter(width=HELP_WIDTH)
|
||||||
parser = OptionParser(version=version_str, formatter=help_formatter)
|
parser = OptionParser(version=version_str, formatter=help_formatter)
|
||||||
parser.add_option("-c", "--component",
|
|
||||||
action="append",
|
# Root options
|
||||||
dest="component",
|
|
||||||
help="openstack component: %s" % (_format_list(settings.COMPONENT_NAMES)))
|
|
||||||
parser.add_option("-v", "--verbose",
|
parser.add_option("-v", "--verbose",
|
||||||
action="append_const",
|
action="append_const",
|
||||||
const=1,
|
const=1,
|
||||||
@ -52,7 +50,14 @@ def parse():
|
|||||||
help=("perform ACTION but do not actually run any of the commands"
|
help=("perform ACTION but do not actually run any of the commands"
|
||||||
" that would normally complete ACTION: (default: %default)"))
|
" that would normally complete ACTION: (default: %default)"))
|
||||||
|
|
||||||
|
# Install/start/stop/uninstall specific options
|
||||||
base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options")
|
base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options")
|
||||||
|
base_group.add_option("-p", "--persona",
|
||||||
|
action="store",
|
||||||
|
type="string",
|
||||||
|
dest="persona_fn",
|
||||||
|
metavar="FILE",
|
||||||
|
help="required persona yaml file to apply")
|
||||||
base_group.add_option("-a", "--action",
|
base_group.add_option("-a", "--action",
|
||||||
action="store",
|
action="store",
|
||||||
type="string",
|
type="string",
|
||||||
@ -66,28 +71,15 @@ def parse():
|
|||||||
metavar="DIR",
|
metavar="DIR",
|
||||||
help=("empty root DIR for install or "
|
help=("empty root DIR for install or "
|
||||||
"DIR with existing components for start/stop/uninstall"))
|
"DIR with existing components for start/stop/uninstall"))
|
||||||
base_group.add_option("-i", "--ignore-deps",
|
|
||||||
action="store_false",
|
|
||||||
dest="ensure_deps",
|
|
||||||
help="ignore dependencies when performing ACTION")
|
|
||||||
base_group.add_option("--no-prompt-passwords",
|
base_group.add_option("--no-prompt-passwords",
|
||||||
action="store_false",
|
action="store_false",
|
||||||
dest="prompt_for_passwords",
|
dest="prompt_for_passwords",
|
||||||
default=True,
|
default=True,
|
||||||
help="do not prompt the user for passwords",
|
help="do not prompt the user for passwords",
|
||||||
)
|
)
|
||||||
base_group.add_option("-e", "--ensure-deps",
|
|
||||||
action="store_true",
|
|
||||||
dest="ensure_deps",
|
|
||||||
help="ensure dependencies when performing ACTION (default: %default)",
|
|
||||||
default=True)
|
|
||||||
base_group.add_option("-r", "--ref-component",
|
|
||||||
action="append",
|
|
||||||
dest="ref_components",
|
|
||||||
metavar="COMPONENT",
|
|
||||||
help="component which will not have ACTION applied but will be referenced as if it was (ACTION dependent)")
|
|
||||||
parser.add_option_group(base_group)
|
parser.add_option_group(base_group)
|
||||||
|
|
||||||
|
# Uninstall and stop options
|
||||||
stop_un_group = OptionGroup(parser, "Uninstall & stop specific options")
|
stop_un_group = OptionGroup(parser, "Uninstall & stop specific options")
|
||||||
stop_un_group.add_option("-n", "--no-force",
|
stop_un_group.add_option("-n", "--no-force",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@ -104,18 +96,16 @@ def parse():
|
|||||||
default=False)
|
default=False)
|
||||||
parser.add_option_group(un_group)
|
parser.add_option_group(un_group)
|
||||||
|
|
||||||
#extract only what we care about
|
# Extract only what we care about
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
output = dict()
|
output = dict()
|
||||||
output['components'] = options.component or list()
|
|
||||||
output['dir'] = options.dir or ""
|
output['dir'] = options.dir or ""
|
||||||
output['dryrun'] = options.dryrun or False
|
output['dryrun'] = options.dryrun or False
|
||||||
output['ref_components'] = options.ref_components or list()
|
|
||||||
output['action'] = options.action or ""
|
output['action'] = options.action or ""
|
||||||
output['force'] = not options.force
|
output['force'] = not options.force
|
||||||
output['ignore_deps'] = not options.ensure_deps
|
|
||||||
output['keep_old'] = options.keep_old
|
output['keep_old'] = options.keep_old
|
||||||
output['extras'] = args
|
output['extras'] = args
|
||||||
|
output['persona_fn'] = options.persona_fn
|
||||||
output['verbosity'] = len(options.verbosity)
|
output['verbosity'] = len(options.verbosity)
|
||||||
output['prompt_for_passwords'] = options.prompt_for_passwords
|
output['prompt_for_passwords'] = options.prompt_for_passwords
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.packager")
|
LOG = logging.getLogger("devstack.packager")
|
||||||
@ -26,29 +25,29 @@ class Packager(object):
|
|||||||
self.distro = distro
|
self.distro = distro
|
||||||
self.keep_packages = keep_packages
|
self.keep_packages = keep_packages
|
||||||
|
|
||||||
def install_batch(self, pkgs):
|
def install(self, pkg):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def remove_batch(self, pkgs):
|
def remove_batch(self, pkgs):
|
||||||
if not self.keep_packages:
|
if not self.keep_packages:
|
||||||
return self._remove_batch(pkgs)
|
return self._remove_batch(pkgs)
|
||||||
return []
|
return list()
|
||||||
|
|
||||||
def pre_install(self, pkgs, installparams=None):
|
def pre_install(self, pkgs, params=None):
|
||||||
for packageinfo in pkgs:
|
for info in pkgs:
|
||||||
preinstallcmds = packageinfo.get(settings.PRE_INSTALL)
|
cmds = info.get('pre-install')
|
||||||
if preinstallcmds:
|
if cmds:
|
||||||
LOG.info("Running pre-install commands for package %s.",
|
LOG.info("Running pre-install commands for package %s.",
|
||||||
packageinfo['name'])
|
info['name'])
|
||||||
utils.execute_template(*preinstallcmds, params=installparams)
|
utils.execute_template(*cmds, params=params)
|
||||||
|
|
||||||
def post_install(self, pkgs, installparams=None):
|
def post_install(self, pkgs, params=None):
|
||||||
for packageinfo in pkgs:
|
for info in pkgs:
|
||||||
postinstallcmds = packageinfo.get(settings.POST_INSTALL)
|
cmds = info.get('post-install')
|
||||||
if postinstallcmds and len(postinstallcmds):
|
if cmds:
|
||||||
LOG.info("Running post-install commands for package %s.",
|
LOG.info("Running post-install commands for package %s.",
|
||||||
packageinfo['name'])
|
info['name'])
|
||||||
utils.execute_template(*postinstallcmds, params=installparams)
|
utils.execute_template(*cmds, params=params)
|
||||||
|
|
||||||
def _remove_batch(self, pkgs):
|
def _remove_batch(self, pkgs):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -14,30 +14,28 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from tempfile import TemporaryFile
|
|
||||||
import time
|
|
||||||
|
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import packager as pack
|
from devstack import packager as pack
|
||||||
from devstack import settings
|
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.packaging.apt")
|
LOG = logging.getLogger("devstack.packaging.apt")
|
||||||
|
|
||||||
#base apt commands
|
# Base apt commands
|
||||||
APT_GET = ['apt-get']
|
APT_GET = ['apt-get']
|
||||||
APT_PURGE = ["purge", "-y"]
|
APT_PURGE = ["purge", "-y"]
|
||||||
APT_REMOVE = ["remove", "-y"]
|
APT_REMOVE = ["remove", "-y"]
|
||||||
APT_INSTALL = ["install", "-y"]
|
APT_INSTALL = ["install", "-y"]
|
||||||
APT_AUTOREMOVE = ['autoremove', '-y']
|
APT_AUTOREMOVE = ['autoremove', '-y']
|
||||||
|
|
||||||
#should we use remove or purge?
|
# Should we use remove or purge?
|
||||||
APT_DO_REMOVE = APT_PURGE
|
APT_DO_REMOVE = APT_PURGE
|
||||||
|
|
||||||
#make sure its non-interactive
|
# Make sure its non-interactive
|
||||||
|
# http://awaseconfigurations.wordpress.com/tag/debian_frontend/
|
||||||
ENV_ADDITIONS = {'DEBIAN_FRONTEND': 'noninteractive'}
|
ENV_ADDITIONS = {'DEBIAN_FRONTEND': 'noninteractive'}
|
||||||
|
|
||||||
#apt separates its pkg names and versions with a equal sign
|
# Apt separates its pkg names and versions with a equal sign
|
||||||
VERSION_TEMPL = "%s=%s"
|
VERSION_TEMPL = "%s=%s"
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +58,6 @@ class AptPackager(pack.Packager):
|
|||||||
**kargs)
|
**kargs)
|
||||||
|
|
||||||
def _remove_batch(self, pkgs):
|
def _remove_batch(self, pkgs):
|
||||||
#form the needed commands
|
|
||||||
cmds = []
|
cmds = []
|
||||||
which_removed = []
|
which_removed = []
|
||||||
for info in pkgs:
|
for info in pkgs:
|
||||||
@ -78,53 +75,22 @@ class AptPackager(pack.Packager):
|
|||||||
if cmds:
|
if cmds:
|
||||||
cmd = APT_GET + APT_DO_REMOVE + cmds
|
cmd = APT_GET + APT_DO_REMOVE + cmds
|
||||||
self._execute_apt(cmd)
|
self._execute_apt(cmd)
|
||||||
#clean them out (if we did anything)
|
|
||||||
if which_removed and self.auto_remove:
|
if which_removed and self.auto_remove:
|
||||||
cmd = APT_GET + APT_AUTOREMOVE
|
cmd = APT_GET + APT_AUTOREMOVE
|
||||||
self._execute_apt(cmd)
|
self._execute_apt(cmd)
|
||||||
return which_removed
|
return which_removed
|
||||||
|
|
||||||
def install_batch(self, pkgs):
|
def install(self, pkg):
|
||||||
#form the needed commands
|
name = pkg['name']
|
||||||
cmds = []
|
if self._pkg_install_special(name, pkg):
|
||||||
for info in pkgs:
|
return
|
||||||
name = info['name']
|
else:
|
||||||
if self._pkg_install_special(name, info):
|
pkg_full = self._format_pkg(name, pkg.get("version"))
|
||||||
continue
|
cmd = APT_GET + APT_INSTALL + [pkg_full]
|
||||||
pkg_full = self._format_pkg(name, info.get("version"))
|
|
||||||
cmds.append(pkg_full)
|
|
||||||
#install them
|
|
||||||
if cmds:
|
|
||||||
cmd = APT_GET + APT_INSTALL + cmds
|
|
||||||
self._execute_apt(cmd)
|
self._execute_apt(cmd)
|
||||||
|
|
||||||
def _pkg_remove_special(self, name, pkginfo):
|
def _pkg_remove_special(self, name, info):
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
|
||||||
if name == 'rabbitmq-server' and self.distro.name == settings.UBUNTU11:
|
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
|
||||||
LOG.info("Handling special remove of %s." % (name))
|
|
||||||
pkg_full = self._format_pkg(name, pkginfo.get("version"))
|
|
||||||
cmd = APT_GET + APT_REMOVE + [pkg_full]
|
|
||||||
self._execute_apt(cmd)
|
|
||||||
#probably useful to do this
|
|
||||||
time.sleep(1)
|
|
||||||
#purge
|
|
||||||
cmd = APT_GET + APT_PURGE + [pkg_full]
|
|
||||||
self._execute_apt(cmd)
|
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _pkg_install_special(self, name, pkginfo):
|
def _pkg_install_special(self, name, info):
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
|
||||||
if name == 'rabbitmq-server' and self.distro.name == settings.UBUNTU11:
|
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
|
|
||||||
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
|
|
||||||
LOG.info("Handling special install of %s." % (name))
|
|
||||||
#this seems to be a temporary fix for that bug
|
|
||||||
with TemporaryFile() as f:
|
|
||||||
pkg_full = self._format_pkg(name, pkginfo.get("version"))
|
|
||||||
cmd = APT_GET + APT_INSTALL + [pkg_full]
|
|
||||||
self._execute_apt(cmd, stdout_fh=f, stderr_fh=f)
|
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
@ -16,23 +16,22 @@
|
|||||||
|
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import packager as pack
|
from devstack import packager as pack
|
||||||
from devstack import settings
|
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.packaging.yum")
|
LOG = logging.getLogger("devstack.packaging.yum")
|
||||||
|
|
||||||
#root yum command
|
# Root yum command
|
||||||
YUM_CMD = ['yum']
|
YUM_CMD = ['yum']
|
||||||
|
|
||||||
#tolerant is enabled since we might already have it installed/erased
|
# Tolerant is enabled since we might already have it installed/erased
|
||||||
YUM_INSTALL = ["install", "-y", "-t"]
|
YUM_INSTALL = ["install", "-y", "-t"]
|
||||||
YUM_REMOVE = ['erase', '-y', "-t"]
|
YUM_REMOVE = ['erase', '-y', "-t"]
|
||||||
|
|
||||||
#yum separates its pkg names and versions with a dash
|
# Yum separates its pkg names and versions with a dash
|
||||||
VERSION_TEMPL = "%s-%s"
|
VERSION_TEMPL = "%s-%s"
|
||||||
|
|
||||||
#need to relink for rhel (not a bug!)
|
# Need to relink for rhel (not a bug!)
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
# TODO: maybe this should be a subclass that handles these differences
|
||||||
RHEL_RELINKS = {
|
RHEL_RELINKS = {
|
||||||
'python-webob1.0': {
|
'python-webob1.0': {
|
||||||
"src": '/usr/lib/python2.6/site-packages/WebOb-1.0.8-py2.6.egg/webob/',
|
"src": '/usr/lib/python2.6/site-packages/WebOb-1.0.8-py2.6.egg/webob/',
|
||||||
@ -61,14 +60,14 @@ class YumPackager(pack.Packager):
|
|||||||
**kargs)
|
**kargs)
|
||||||
|
|
||||||
def _remove_special(self, pkgname, pkginfo):
|
def _remove_special(self, pkgname, pkginfo):
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
# TODO: maybe this should be a subclass that handles these differences
|
||||||
if self.distro.name == settings.RHEL6 and pkgname in RHEL_RELINKS:
|
# if self.distro.name == settings.RHEL6 and pkgname in RHEL_RELINKS:
|
||||||
#we don't return true here so that
|
# #we don't return true here so that
|
||||||
#the normal package cleanup happens
|
# #the normal package cleanup happens
|
||||||
sh.unlink(RHEL_RELINKS.get(pkgname).get("tgt"))
|
# sh.unlink(RHEL_RELINKS.get(pkgname).get("tgt"))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
# TODO: maybe this should be a subclass that handles these differences
|
||||||
def _install_rhel_relinks(self, pkgname, pkginfo):
|
def _install_rhel_relinks(self, pkgname, pkginfo):
|
||||||
full_pkg_name = self._format_pkg_name(pkgname, pkginfo.get("version"))
|
full_pkg_name = self._format_pkg_name(pkgname, pkginfo.get("version"))
|
||||||
install_cmd = YUM_CMD + YUM_INSTALL + [full_pkg_name]
|
install_cmd = YUM_CMD + YUM_INSTALL + [full_pkg_name]
|
||||||
@ -82,10 +81,11 @@ class YumPackager(pack.Packager):
|
|||||||
sh.symlink(src, tgt)
|
sh.symlink(src, tgt)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
#TODO: maybe this should be a subclass that handles these differences
|
# TODO: maybe this should be a subclass that handles these differences
|
||||||
def _install_special(self, pkgname, pkginfo):
|
def _install_special(self, pkgname, pkginfo):
|
||||||
if self.distro.name == settings.RHEL6 and pkgname in RHEL_RELINKS:
|
# FIXME:
|
||||||
return self._install_rhel_relinks(pkgname, pkginfo)
|
# if self.distro.name == settings.RHEL6 and pkgname in RHEL_RELINKS:
|
||||||
|
# return self._install_rhel_relinks(pkgname, pkginfo)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def install_batch(self, pkgs):
|
def install_batch(self, pkgs):
|
||||||
|
@ -18,40 +18,33 @@
|
|||||||
from devstack import exceptions as excp
|
from devstack import exceptions as excp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import settings
|
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.pip")
|
LOG = logging.getLogger("devstack.pip")
|
||||||
PIP_UNINSTALL_CMD_OPTS = ['-y', '-q']
|
PIP_UNINSTALL_CMD_OPTS = ['-y', '-q']
|
||||||
PIP_INSTALL_CMD_OPTS = ['-q']
|
PIP_INSTALL_CMD_OPTS = ['-q']
|
||||||
|
|
||||||
|
|
||||||
def install(pips, distro):
|
def install(pip, distro):
|
||||||
pipnames = sorted(pips.keys())
|
name = pip['name']
|
||||||
root_cmd = distro.commands.get('pip', 'pip')
|
root_cmd = distro.get_command('pip')
|
||||||
LOG.info("Installing python packages (%s) using command (%s)" % (", ".join(pipnames), root_cmd))
|
LOG.audit("Installing python package (%s) using pip command (%s)" % (name, root_cmd))
|
||||||
for name in pipnames:
|
name_full = name
|
||||||
pipfull = name
|
version = pip.get('version')
|
||||||
pipinfo = pips.get(name)
|
if version is not None:
|
||||||
if pipinfo and pipinfo.get('version'):
|
name_full += "==" + str(version)
|
||||||
version = pipinfo.get('version')
|
real_cmd = [root_cmd, 'install'] + PIP_INSTALL_CMD_OPTS
|
||||||
if version is not None:
|
options = pip.get('options')
|
||||||
pipfull = pipfull + "==" + str(version)
|
if options is not None:
|
||||||
LOG.debug("Installing python package (%s)" % (pipfull))
|
LOG.debug("Using pip options: %s" % (str(options)))
|
||||||
real_cmd = [root_cmd, 'install']
|
real_cmd += [str(options)]
|
||||||
real_cmd += PIP_INSTALL_CMD_OPTS
|
real_cmd += [name_full]
|
||||||
options = pipinfo.get('options')
|
sh.execute(*real_cmd, run_as_root=True)
|
||||||
if options is not None:
|
|
||||||
LOG.debug("Using pip options: %s" % (str(options)))
|
|
||||||
real_cmd += [str(options)]
|
|
||||||
real_cmd += [pipfull]
|
|
||||||
sh.execute(*real_cmd, run_as_root=True)
|
|
||||||
|
|
||||||
|
|
||||||
def uninstall(pips, distro, skip_errors=True):
|
def uninstall_batch(pips, distro, skip_errors=True):
|
||||||
pipnames = sorted(pips.keys())
|
names = set([p['name'] for p in pips])
|
||||||
root_cmd = distro.commands.get('pip', 'pip')
|
root_cmd = distro.get_command('pip')
|
||||||
LOG.info("Uninstalling python packages (%s) using command (%s)" % (", ".join(pipnames), root_cmd))
|
for name in names:
|
||||||
for name in pipnames:
|
|
||||||
try:
|
try:
|
||||||
LOG.debug("Uninstalling python package (%s)" % (name))
|
LOG.debug("Uninstalling python package (%s)" % (name))
|
||||||
cmd = [root_cmd, 'uninstall'] + PIP_UNINSTALL_CMD_OPTS + [str(name)]
|
cmd = [root_cmd, 'uninstall'] + PIP_UNINSTALL_CMD_OPTS + [str(name)]
|
||||||
|
@ -14,22 +14,22 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License..
|
# under the License..
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
from devstack import env_rc
|
from devstack import env_rc
|
||||||
from devstack import exceptions as excp
|
from devstack import exceptions as excp
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import settings
|
from devstack import settings
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import passwords
|
||||||
|
|
||||||
from devstack.progs import common
|
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.progs.actions")
|
LOG = logging.getLogger("devstack.progs.actions")
|
||||||
|
|
||||||
# For actions in this list we will reverse the component order
|
# For actions in this list we will reverse the component order
|
||||||
_REVERSE_ACTIONS = [settings.UNINSTALL, settings.STOP]
|
REVERSE_ACTIONS = [settings.UNINSTALL, settings.STOP]
|
||||||
|
|
||||||
# For these actions we will attempt to make an rc file if it does not exist
|
# For these actions we will attempt to make an rc file if it does not exist
|
||||||
_RC_FILE_MAKE_ACTIONS = [settings.INSTALL]
|
RC_FILE_MAKE_ACTIONS = [settings.INSTALL]
|
||||||
|
|
||||||
# The order of which uninstalls happen + message of what is happening
|
# The order of which uninstalls happen + message of what is happening
|
||||||
# (before and after)
|
# (before and after)
|
||||||
@ -138,125 +138,96 @@ PREQ_ACTIONS = {
|
|||||||
|
|
||||||
|
|
||||||
class ActionRunner(object):
|
class ActionRunner(object):
|
||||||
def __init__(self, distro, action, directory, config,
|
def __init__(self, distro, action, cfg, **kargs):
|
||||||
pw_gen, pkg_manager,
|
|
||||||
**kargs):
|
|
||||||
self.distro = distro
|
self.distro = distro
|
||||||
self.action = action
|
self.action = action
|
||||||
self.directory = directory
|
self.cfg = cfg
|
||||||
self.cfg = config
|
self.pw_gen = passwords.PasswordGenerator(self.cfg, kargs.get('prompt_for_passwords', True))
|
||||||
self.pw_gen = pw_gen
|
pkg_cls = distro.get_packager_factory()
|
||||||
self.pkg_manager = pkg_manager
|
self.keep_old = kargs.get('keep_old')
|
||||||
self.kargs = kargs
|
self.pkg_manager = pkg_cls(self.distro, self.keep_old)
|
||||||
self.components = dict()
|
|
||||||
def_components = common.get_default_components()
|
|
||||||
unclean_components = kargs.pop("components")
|
|
||||||
if not unclean_components:
|
|
||||||
self.components = def_components
|
|
||||||
else:
|
|
||||||
for (c, opts) in unclean_components.items():
|
|
||||||
if opts is None and c in def_components:
|
|
||||||
self.components[c] = def_components[c]
|
|
||||||
elif opts is None:
|
|
||||||
self.components[c] = list()
|
|
||||||
else:
|
|
||||||
self.components[c] = opts
|
|
||||||
self.force = kargs.get('force', False)
|
self.force = kargs.get('force', False)
|
||||||
self.ignore_deps = kargs.get('ignore_deps', False)
|
self.kargs = kargs
|
||||||
self.ref_components = kargs.get("ref_components")
|
|
||||||
self.gen_rc = action in _RC_FILE_MAKE_ACTIONS
|
|
||||||
|
|
||||||
def _get_components(self):
|
def _apply_reverse(self, action, component_order):
|
||||||
return dict(self.components)
|
adjusted_order = list(component_order)
|
||||||
|
if action in REVERSE_ACTIONS:
|
||||||
|
adjusted_order.reverse()
|
||||||
|
return adjusted_order
|
||||||
|
|
||||||
def _order_components(self, components):
|
def _load_persona(self, persona_fn):
|
||||||
adjusted_components = dict(components)
|
persona_fn = sh.abspth(persona_fn)
|
||||||
if self.ignore_deps:
|
LOG.audit("Loading persona from file [%s]", persona_fn)
|
||||||
return (adjusted_components, list(components.keys()))
|
contents = ''
|
||||||
all_components = self.distro.resolve_component_dependencies(
|
with open(persona_fn, "r") as fh:
|
||||||
list(components.keys())
|
contents = fh.read()
|
||||||
)
|
return self._verify_persona(yaml.load(contents), persona_fn)
|
||||||
component_diff = set(all_components.keys()).difference(components.keys())
|
|
||||||
if component_diff:
|
|
||||||
LOG.info("Activating dependencies: [%s]",
|
|
||||||
", ".join(sorted(component_diff))
|
|
||||||
)
|
|
||||||
for new_component in component_diff:
|
|
||||||
adjusted_components[new_component] = []
|
|
||||||
return (adjusted_components, utils.get_components_order(all_components))
|
|
||||||
|
|
||||||
def _inject_references(self, components):
|
def _verify_persona(self, persona, fn):
|
||||||
ref_components = utils.parse_components(self.ref_components)
|
# Some sanity checks
|
||||||
adjusted_components = dict(components)
|
try:
|
||||||
for c in ref_components.keys():
|
if self.distro.name not in persona['supports']:
|
||||||
if c not in components:
|
raise RuntimeError("Persona does not support distro %s"
|
||||||
adjusted_components[c] = ref_components.get(c)
|
% (self.distro.name))
|
||||||
return adjusted_components
|
for c in persona['components']:
|
||||||
|
if not self.distro.known_component(c):
|
||||||
|
raise RuntimeError("Distro %s does not support component %s" %
|
||||||
|
(self.distro.name, c))
|
||||||
|
except (KeyError, RuntimeError) as e:
|
||||||
|
msg = ("Could not validate persona defined in [%s] due to: %s"
|
||||||
|
% (fn, e))
|
||||||
|
raise excp.ConfigException(msg)
|
||||||
|
return persona
|
||||||
|
|
||||||
def _instantiate_components(self, components):
|
def _construct_instances(self, persona, action, root_dir):
|
||||||
all_instances = dict()
|
components = persona['components'] # Required
|
||||||
for component in components.keys():
|
desired_subsystems = persona.get('subsystems', dict()) # Not required
|
||||||
cls = self.distro.get_component_action_class(component,
|
instances = dict()
|
||||||
self.action)
|
for c in components:
|
||||||
LOG.debug('instantiating %s to handle %s for %s',
|
(cls, my_info) = self.distro.extract_component(c, action)
|
||||||
cls, self.action, component)
|
LOG.debug("Constructing class %s" % (cls))
|
||||||
instance = cls(component_name=component,
|
cls_kvs = dict()
|
||||||
instances=all_instances,
|
cls_kvs['runner'] = self
|
||||||
runner=self,
|
cls_kvs['component_dir'] = sh.joinpths(root_dir, c)
|
||||||
root_dir=self.directory,
|
cls_kvs['subsystem_info'] = my_info.pop('subsystems', dict())
|
||||||
component_options=self.distro.components[component],
|
cls_kvs['all_instances'] = instances
|
||||||
keep_old=self.kargs.get("keep_old")
|
cls_kvs['name'] = c
|
||||||
)
|
cls_kvs['keep_old'] = self.keep_old
|
||||||
all_instances[component] = instance
|
cls_kvs['desired_subsystems'] = set(desired_subsystems.get(c, list()))
|
||||||
return all_instances
|
# The above is not overrideable...
|
||||||
|
for (k, v) in my_info.items():
|
||||||
|
if k not in cls_kvs:
|
||||||
|
cls_kvs[k] = v
|
||||||
|
LOG.debug("Using arg map %s", cls_kvs)
|
||||||
|
cls_args = list()
|
||||||
|
LOG.debug("Using arg list %s", cls_args)
|
||||||
|
instances[c] = cls(*cls_args, **cls_kvs)
|
||||||
|
return instances
|
||||||
|
|
||||||
def _run_preqs(self, components, component_order):
|
def _verify_components(self, component_order, instances):
|
||||||
if not (self.action in PREQ_ACTIONS):
|
LOG.info("Verifying that the components are ready to rock-n-roll.")
|
||||||
return
|
|
||||||
(check_functor, preq_action) = PREQ_ACTIONS[self.action]
|
|
||||||
instances = self._instantiate_components(components)
|
|
||||||
preq_components = dict()
|
|
||||||
for c in component_order:
|
for c in component_order:
|
||||||
instance = instances[c]
|
instance = instances[c]
|
||||||
if check_functor(instance):
|
instance.verify()
|
||||||
preq_components[c] = components[c]
|
|
||||||
if preq_components:
|
|
||||||
LOG.info("Having to activate prerequisite action [%s] for %s components." % (preq_action, len(preq_components)))
|
|
||||||
preq_runner = ActionRunner(distro=self.distro,
|
|
||||||
action=preq_action,
|
|
||||||
directory=self.directory,
|
|
||||||
config=self.cfg,
|
|
||||||
pw_gen=self.pw_gen,
|
|
||||||
pkg_manager=self.pkg_manager,
|
|
||||||
components=preq_components,
|
|
||||||
**self.kargs)
|
|
||||||
preq_runner.run()
|
|
||||||
|
|
||||||
def _pre_run(self, instances, component_order):
|
def _warm_components(self, component_order, instances):
|
||||||
if not sh.isdir(self.directory):
|
|
||||||
sh.mkdir(self.directory)
|
|
||||||
LOG.info("Verifying that the components are ready to rock-n-roll.")
|
|
||||||
for component in component_order:
|
|
||||||
inst = instances[component]
|
|
||||||
inst.verify()
|
|
||||||
LOG.info("Warming up your component configurations (ie so you won't be prompted later)")
|
LOG.info("Warming up your component configurations (ie so you won't be prompted later)")
|
||||||
for component in component_order:
|
for c in component_order:
|
||||||
inst = instances[component]
|
instance = instances[c]
|
||||||
inst.warm_configs()
|
instance.warm_configs()
|
||||||
if self.gen_rc:
|
|
||||||
writer = env_rc.RcWriter(self.cfg, self.pw_gen, self.directory)
|
|
||||||
if not sh.isfile(settings.OSRC_FN):
|
|
||||||
LOG.info("Generating a file at [%s] that will contain your environment settings." % (settings.OSRC_FN))
|
|
||||||
writer.write(settings.OSRC_FN)
|
|
||||||
else:
|
|
||||||
LOG.info("Updating a file at [%s] that contains your environment settings." % (settings.OSRC_FN))
|
|
||||||
am_upd = writer.update(settings.OSRC_FN)
|
|
||||||
LOG.info("Updated [%s] settings in rc file [%s]" % (am_upd, settings.OSRC_FN))
|
|
||||||
|
|
||||||
def _run_instances(self, instances, component_order):
|
def _write_rc_file(self, root_dir):
|
||||||
component_order = self._apply_reverse(component_order)
|
writer = env_rc.RcWriter(self.cfg, self.pw_gen, root_dir)
|
||||||
LOG.info("Running in the following order: %s" % ("->".join(component_order)))
|
if not sh.isfile(settings.OSRC_FN):
|
||||||
for (start_msg, functor, end_msg) in ACTION_MP[self.action]:
|
LOG.info("Generating a file at [%s] that will contain your environment settings." % (settings.OSRC_FN))
|
||||||
|
writer.write(settings.OSRC_FN)
|
||||||
|
else:
|
||||||
|
LOG.info("Updating a file at [%s] that contains your environment settings." % (settings.OSRC_FN))
|
||||||
|
am_upd = writer.update(settings.OSRC_FN)
|
||||||
|
LOG.info("Updated [%s] settings in rc file [%s]" % (am_upd, settings.OSRC_FN))
|
||||||
|
|
||||||
|
def _run_instances(self, action, component_order, instances):
|
||||||
|
for (start_msg, functor, end_msg) in ACTION_MP[action]:
|
||||||
for c in component_order:
|
for c in component_order:
|
||||||
instance = instances[c]
|
instance = instances[c]
|
||||||
if start_msg:
|
if start_msg:
|
||||||
@ -271,19 +242,33 @@ class ActionRunner(object):
|
|||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _apply_reverse(self, component_order):
|
def _run_action(self, persona, action, root_dir):
|
||||||
adjusted_order = list(component_order)
|
LOG.info("Running action [%s] using root directory [%s]" % (action, root_dir))
|
||||||
if self.action in _REVERSE_ACTIONS:
|
instances = self._construct_instances(persona, action, root_dir)
|
||||||
adjusted_order.reverse()
|
if action in PREQ_ACTIONS:
|
||||||
return adjusted_order
|
(check_functor, preq_action) = PREQ_ACTIONS[action]
|
||||||
|
checks_passed_components = list()
|
||||||
|
for (c, instance) in instances.items():
|
||||||
|
if check_functor(instance):
|
||||||
|
checks_passed_components.append(c)
|
||||||
|
if checks_passed_components:
|
||||||
|
LOG.info("Activating prerequisite action [%s] requested by (%s) components."
|
||||||
|
% (preq_action, ", ".join(checks_passed_components)))
|
||||||
|
self._run_action(persona, preq_action, root_dir)
|
||||||
|
component_order = self._apply_reverse(action, persona['components'])
|
||||||
|
LOG.info("Activating components [%s] (in that order) for action [%s]" %
|
||||||
|
("->".join(component_order), action))
|
||||||
|
self._verify_components(component_order, instances)
|
||||||
|
self._warm_components(component_order, instances)
|
||||||
|
if action in RC_FILE_MAKE_ACTIONS:
|
||||||
|
self._write_rc_file(root_dir)
|
||||||
|
self._run_instances(action, component_order, instances)
|
||||||
|
|
||||||
def _start(self, components, component_order):
|
def _setup_root(self, root_dir):
|
||||||
LOG.info("Activating components required to complete action [%s]" % (self.action))
|
if not sh.isdir(root_dir):
|
||||||
instances = self._instantiate_components(components)
|
sh.mkdir(root_dir)
|
||||||
self._pre_run(instances, component_order)
|
|
||||||
self._run_preqs(components, component_order)
|
|
||||||
self._run_instances(instances, component_order)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self, persona_fn, root_dir):
|
||||||
(components, component_order) = self._order_components(self._get_components())
|
persona = self._load_persona(persona_fn)
|
||||||
self._start(self._inject_references(components), component_order)
|
self._setup_root(root_dir)
|
||||||
|
self._run_action(persona, self.action, root_dir)
|
||||||
|
@ -1,190 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from devstack import cfg
|
|
||||||
from devstack import exceptions as excp
|
|
||||||
from devstack import settings
|
|
||||||
from devstack import shell as sh
|
|
||||||
|
|
||||||
from devstack.components import db
|
|
||||||
from devstack.components import glance
|
|
||||||
from devstack.components import horizon
|
|
||||||
from devstack.components import keystone
|
|
||||||
from devstack.components import keystone_client
|
|
||||||
from devstack.components import melange
|
|
||||||
from devstack.components import melange_client
|
|
||||||
from devstack.components import nova
|
|
||||||
from devstack.components import nova_client
|
|
||||||
from devstack.components import novnc
|
|
||||||
from devstack.components import quantum
|
|
||||||
from devstack.components import quantum_client
|
|
||||||
from devstack.components import rabbit
|
|
||||||
from devstack.components import swift
|
|
||||||
|
|
||||||
from devstack.packaging import apt
|
|
||||||
from devstack.packaging import yum
|
|
||||||
|
|
||||||
# This determines what classes to use to install/uninstall/...
|
|
||||||
# ACTION_CLASSES = {
|
|
||||||
# settings.INSTALL: {
|
|
||||||
# settings.DB: db.DBInstaller,
|
|
||||||
# settings.GLANCE: glance.GlanceInstaller,
|
|
||||||
# settings.HORIZON: horizon.HorizonInstaller,
|
|
||||||
# settings.KEYSTONE: keystone.KeystoneInstaller,
|
|
||||||
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientInstaller,
|
|
||||||
# settings.MELANGE: melange.MelangeInstaller,
|
|
||||||
# settings.MELANGE_CLIENT: melange_client.MelangeClientInstaller,
|
|
||||||
# settings.NOVA: nova.NovaInstaller,
|
|
||||||
# settings.NOVA_CLIENT: nova_client.NovaClientInstaller,
|
|
||||||
# settings.NOVNC: novnc.NoVNCInstaller,
|
|
||||||
# settings.QUANTUM: quantum.QuantumInstaller,
|
|
||||||
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientInstaller,
|
|
||||||
# settings.RABBIT: rabbit.RabbitInstaller,
|
|
||||||
# settings.SWIFT: swift.SwiftInstaller,
|
|
||||||
# },
|
|
||||||
# settings.UNINSTALL: {
|
|
||||||
# settings.DB: db.DBUninstaller,
|
|
||||||
# settings.GLANCE: glance.GlanceUninstaller,
|
|
||||||
# settings.HORIZON: horizon.HorizonUninstaller,
|
|
||||||
# settings.KEYSTONE: keystone.KeystoneUninstaller,
|
|
||||||
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientUninstaller,
|
|
||||||
# settings.MELANGE: melange.MelangeUninstaller,
|
|
||||||
# settings.MELANGE_CLIENT: melange_client.MelangeClientUninstaller,
|
|
||||||
# settings.NOVA: nova.NovaUninstaller,
|
|
||||||
# settings.NOVA_CLIENT: nova_client.NovaClientUninstaller,
|
|
||||||
# settings.NOVNC: novnc.NoVNCUninstaller,
|
|
||||||
# settings.QUANTUM: quantum.QuantumUninstaller,
|
|
||||||
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientUninstaller,
|
|
||||||
# settings.RABBIT: rabbit.RabbitUninstaller,
|
|
||||||
# settings.SWIFT: swift.SwiftUninstaller,
|
|
||||||
# },
|
|
||||||
# settings.START: {
|
|
||||||
# settings.DB: db.DBRuntime,
|
|
||||||
# settings.GLANCE: glance.GlanceRuntime,
|
|
||||||
# settings.HORIZON: horizon.HorizonRuntime,
|
|
||||||
# settings.KEYSTONE: keystone.KeystoneRuntime,
|
|
||||||
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime,
|
|
||||||
# settings.MELANGE: melange.MelangeRuntime,
|
|
||||||
# settings.MELANGE_CLIENT: melange_client.MelangeClientRuntime,
|
|
||||||
# settings.NOVA: nova.NovaRuntime,
|
|
||||||
# settings.NOVA_CLIENT: nova_client.NovaClientRuntime,
|
|
||||||
# settings.NOVNC: novnc.NoVNCRuntime,
|
|
||||||
# settings.QUANTUM: quantum.QuantumRuntime,
|
|
||||||
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientRuntime,
|
|
||||||
# settings.RABBIT: rabbit.RabbitRuntime,
|
|
||||||
# settings.SWIFT: swift.SwiftRuntime,
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # Just a copy
|
|
||||||
# ACTION_CLASSES[settings.STOP] = ACTION_CLASSES[settings.START]
|
|
||||||
|
|
||||||
# Used only for figuring out deps
|
|
||||||
_FAKE_ROOT_DIR = tempfile.gettempdir()
|
|
||||||
|
|
||||||
# This map controls which distro has
|
|
||||||
# which package management class
|
|
||||||
_PKGR_MAP = {
|
|
||||||
settings.UBUNTU11: apt.AptPackager,
|
|
||||||
settings.RHEL6: yum.YumPackager,
|
|
||||||
settings.FEDORA16: yum.YumPackager,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_default_components():
|
|
||||||
def_components = dict()
|
|
||||||
def_components[settings.GLANCE] = [
|
|
||||||
glance.GAPI,
|
|
||||||
glance.GREG,
|
|
||||||
]
|
|
||||||
def_components[settings.KEYSTONE] = []
|
|
||||||
def_components[settings.NOVA] = [
|
|
||||||
nova.NAPI,
|
|
||||||
nova.NCAUTH,
|
|
||||||
nova.NCERT,
|
|
||||||
nova.NCPU,
|
|
||||||
nova.NNET,
|
|
||||||
nova.NOBJ,
|
|
||||||
nova.NSCHED,
|
|
||||||
nova.NXVNC,
|
|
||||||
nova.NVOL,
|
|
||||||
]
|
|
||||||
def_components[settings.NOVNC] = []
|
|
||||||
def_components[settings.HORIZON] = []
|
|
||||||
def_components[settings.DB] = []
|
|
||||||
def_components[settings.RABBIT] = []
|
|
||||||
return def_components
|
|
||||||
|
|
||||||
|
|
||||||
def format_secs_taken(secs):
|
|
||||||
output = "%.03f seconds" % (secs)
|
|
||||||
output += " or %.02f minutes" % (secs / 60.0)
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
# def get_action_cls(action_name, component_name, distro=None):
|
|
||||||
# action_cls_map = ACTION_CLASSES.get(action_name)
|
|
||||||
# if not action_cls_map:
|
|
||||||
# raise excp.StackException("Action %s has no component to class mapping" % (action_name))
|
|
||||||
# cls = action_cls_map.get(component_name)
|
|
||||||
# if not cls:
|
|
||||||
# raise excp.StackException("Action %s has no class entry for component %s" % (action_name, component_name))
|
|
||||||
# return cls
|
|
||||||
|
|
||||||
|
|
||||||
def get_packager(distro, keep_packages):
|
|
||||||
cls = _PKGR_MAP.get(distro)
|
|
||||||
if not cls:
|
|
||||||
msg = "No package manager found for distro %s!" % (distro)
|
|
||||||
raise excp.StackException(msg)
|
|
||||||
return cls(distro, keep_packages)
|
|
||||||
|
|
||||||
|
|
||||||
def get_config(cfg_fn=None):
|
|
||||||
if not cfg_fn:
|
|
||||||
cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION)
|
|
||||||
config_instance = cfg.StackConfigParser()
|
|
||||||
config_instance.read(cfg_fn)
|
|
||||||
return config_instance
|
|
||||||
|
|
||||||
|
|
||||||
# def get_components_deps(runner,
|
|
||||||
# action_name,
|
|
||||||
# base_components,
|
|
||||||
# root_dir=None,
|
|
||||||
# distro=None,
|
|
||||||
# ):
|
|
||||||
# all_components = dict()
|
|
||||||
# active_names = list(base_components)
|
|
||||||
# root_dir = root_dir or _FAKE_ROOT_DIR
|
|
||||||
# while len(active_names):
|
|
||||||
# component = active_names.pop()
|
|
||||||
# component_opts = base_components.get(component) or list()
|
|
||||||
# cls = get_action_cls(action_name, component, distro)
|
|
||||||
# instance = cls(instances=list(),
|
|
||||||
# runner=runner,
|
|
||||||
# root_dir=root_dir,
|
|
||||||
# component_options=component_opts,
|
|
||||||
# keep_old=False
|
|
||||||
# )
|
|
||||||
# deps = instance.get_dependencies() or set()
|
|
||||||
# all_components[component] = set(deps)
|
|
||||||
# for d in deps:
|
|
||||||
# if d not in all_components and d not in active_names:
|
|
||||||
# active_names.append(d)
|
|
||||||
# return all_components
|
|
@ -23,17 +23,17 @@ class RunnerBase(object):
|
|||||||
self.trace_dir = trace_dir
|
self.trace_dir = trace_dir
|
||||||
|
|
||||||
def unconfigure(self):
|
def unconfigure(self):
|
||||||
#cleans up anything configured by
|
# Cleans up anything configured by
|
||||||
#this runner for any apps for this component
|
# this runner for any apps for this component
|
||||||
#returns how many files unconfigured
|
# returns how many files unconfigured
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def configure(self, app_name, runtime_info):
|
def configure(self, app_name, runtime_info):
|
||||||
#returns how many files configured
|
# Returns how many files configured
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def start(self, name, runtime_info):
|
def start(self, name, runtime_info):
|
||||||
#returns a file name that contains what was started
|
# Returns a file name that contains what was started
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def stop(self, name):
|
def stop(self, name):
|
||||||
|
@ -31,18 +31,18 @@ from devstack import trace as tr
|
|||||||
|
|
||||||
LOG = logging.getLogger("devstack.runners.fork")
|
LOG = logging.getLogger("devstack.runners.fork")
|
||||||
|
|
||||||
#maximum for the number of available file descriptors (when not found)
|
# Maximum for the number of available file descriptors (when not found)
|
||||||
MAXFD = 2048
|
MAXFD = 2048
|
||||||
|
|
||||||
#how many times we try to kill and how much sleep (seconds) between each try
|
# How many times we try to kill and how much sleep (seconds) between each try
|
||||||
MAX_KILL_TRY = 5
|
MAX_KILL_TRY = 5
|
||||||
SLEEP_TIME = 1
|
SLEEP_TIME = 1
|
||||||
|
|
||||||
#my type
|
# My runner type
|
||||||
RUN_TYPE = settings.RUN_TYPE_FORK
|
RUN_TYPE = settings.RUN_TYPE_FORK
|
||||||
TYPE = settings.RUN_TYPE_TYPE
|
TYPE = settings.RUN_TYPE_TYPE
|
||||||
|
|
||||||
#trace constants
|
# Trace constants
|
||||||
PID_FN = "PID_FN"
|
PID_FN = "PID_FN"
|
||||||
STDOUT_FN = "STDOUT_FN"
|
STDOUT_FN = "STDOUT_FN"
|
||||||
STDERR_FN = "STDERR_FN"
|
STDERR_FN = "STDERR_FN"
|
||||||
@ -50,7 +50,7 @@ ARGS = "ARGS"
|
|||||||
NAME = "NAME"
|
NAME = "NAME"
|
||||||
FORK_TEMPL = "%s.fork"
|
FORK_TEMPL = "%s.fork"
|
||||||
|
|
||||||
#run fork cmds as root?
|
# Run fork cmds as root?
|
||||||
ROOT_GO = True
|
ROOT_GO = True
|
||||||
|
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ class ForkRunner(base.RunnerBase):
|
|||||||
if sh.isfile(pid_file) and sh.isfile(trace_fn):
|
if sh.isfile(pid_file) and sh.isfile(trace_fn):
|
||||||
pid = int(sh.load_file(pid_file).strip())
|
pid = int(sh.load_file(pid_file).strip())
|
||||||
(killed, attempts) = self._stop_pid(pid)
|
(killed, attempts) = self._stop_pid(pid)
|
||||||
#trash the files
|
# Trash the files if it worked
|
||||||
if killed:
|
if killed:
|
||||||
LOG.debug("Killed pid %s after %s attempts" % (pid, attempts))
|
LOG.debug("Killed pid %s after %s attempts" % (pid, attempts))
|
||||||
LOG.debug("Removing pid file %s" % (pid_file))
|
LOG.debug("Removing pid file %s" % (pid_file))
|
||||||
@ -115,22 +115,22 @@ class ForkRunner(base.RunnerBase):
|
|||||||
return (pidfile, stderr, stdout)
|
return (pidfile, stderr, stdout)
|
||||||
|
|
||||||
def _fork_start(self, program, appdir, pid_fn, stdout_fn, stderr_fn, *args):
|
def _fork_start(self, program, appdir, pid_fn, stdout_fn, stderr_fn, *args):
|
||||||
#first child, not the real program
|
# First child, not the real program
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if pid == 0:
|
if pid == 0:
|
||||||
#upon return the calling process shall be the session
|
# Upon return the calling process shall be the session
|
||||||
#leader of this new session,
|
# leader of this new session,
|
||||||
#shall be the process group leader of a new process group,
|
# shall be the process group leader of a new process group,
|
||||||
#and shall have no controlling terminal.
|
# and shall have no controlling terminal.
|
||||||
os.setsid()
|
os.setsid()
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
#fork to get daemon out - this time under init control
|
# Fork to get daemon out - this time under init control
|
||||||
#and now fully detached (no shell possible)
|
# and now fully detached (no shell possible)
|
||||||
if pid == 0:
|
if pid == 0:
|
||||||
#move to where application should be
|
# Move to where application should be
|
||||||
if appdir:
|
if appdir:
|
||||||
os.chdir(appdir)
|
os.chdir(appdir)
|
||||||
#close other fds
|
# Close other fds (or try)
|
||||||
limits = resource.getrlimit(resource.RLIMIT_NOFILE)
|
limits = resource.getrlimit(resource.RLIMIT_NOFILE)
|
||||||
mkfd = limits[1]
|
mkfd = limits[1]
|
||||||
if mkfd == resource.RLIM_INFINITY:
|
if mkfd == resource.RLIM_INFINITY:
|
||||||
@ -141,27 +141,27 @@ class ForkRunner(base.RunnerBase):
|
|||||||
except OSError:
|
except OSError:
|
||||||
#not open, thats ok
|
#not open, thats ok
|
||||||
pass
|
pass
|
||||||
#now adjust stderr and stdout
|
# Now adjust stderr and stdout
|
||||||
if stdout_fn:
|
if stdout_fn:
|
||||||
stdoh = open(stdout_fn, "w")
|
stdoh = open(stdout_fn, "w")
|
||||||
os.dup2(stdoh.fileno(), sys.stdout.fileno())
|
os.dup2(stdoh.fileno(), sys.stdout.fileno())
|
||||||
if stderr_fn:
|
if stderr_fn:
|
||||||
stdeh = open(stderr_fn, "w")
|
stdeh = open(stderr_fn, "w")
|
||||||
os.dup2(stdeh.fileno(), sys.stderr.fileno())
|
os.dup2(stdeh.fileno(), sys.stderr.fileno())
|
||||||
#now exec...
|
# Now exec...
|
||||||
#the arguments to the child process should
|
# Note: The arguments to the child process should
|
||||||
#start with the name of the command being run
|
# start with the name of the command being run
|
||||||
prog_little = os.path.basename(program)
|
prog_little = os.path.basename(program)
|
||||||
actualargs = [prog_little] + list(args)
|
actualargs = [prog_little] + list(args)
|
||||||
os.execlp(program, *actualargs)
|
os.execlp(program, *actualargs)
|
||||||
else:
|
else:
|
||||||
#write out the child pid
|
# Write out the child pid
|
||||||
contents = str(pid) + os.linesep
|
contents = str(pid) + os.linesep
|
||||||
sh.write_file(pid_fn, contents, quiet=True)
|
sh.write_file(pid_fn, contents, quiet=True)
|
||||||
#not exit or sys.exit, this is recommended
|
# Not exit or sys.exit, this is recommended
|
||||||
#since it will do the right cleanups that we want
|
# since it will do the right cleanups that we want
|
||||||
#not calling any atexit functions, which would
|
# not calling any atexit functions, which would
|
||||||
#be bad right now
|
# be bad right now
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
def _do_trace(self, fn, kvs):
|
def _do_trace(self, fn, kvs):
|
||||||
|
@ -30,25 +30,25 @@ from devstack import utils
|
|||||||
|
|
||||||
LOG = logging.getLogger("devstack.runners.screen")
|
LOG = logging.getLogger("devstack.runners.screen")
|
||||||
|
|
||||||
#my type
|
# My running type
|
||||||
RUN_TYPE = settings.RUN_TYPE_SCREEN
|
RUN_TYPE = settings.RUN_TYPE_SCREEN
|
||||||
TYPE = settings.RUN_TYPE_TYPE
|
TYPE = settings.RUN_TYPE_TYPE
|
||||||
|
|
||||||
#trace constants
|
# Trace constants
|
||||||
SCREEN_TEMPL = "%s.screen"
|
SCREEN_TEMPL = "%s.screen"
|
||||||
ARGS = "ARGS"
|
ARGS = "ARGS"
|
||||||
NAME = "NAME"
|
NAME = "NAME"
|
||||||
SESSION_ID = 'SESSION_ID'
|
SESSION_ID = 'SESSION_ID'
|
||||||
|
|
||||||
#screen session name
|
# Screen session name
|
||||||
SESSION_NAME = 'stack'
|
SESSION_NAME = 'stack'
|
||||||
SESSION_DEF_TITLE = SESSION_NAME
|
SESSION_DEF_TITLE = SESSION_NAME
|
||||||
SESSION_NAME_MTCHER = re.compile(r"^\s*([\d]+\.%s)\s*(.*)$" % (SESSION_NAME))
|
SESSION_NAME_MTCHER = re.compile(r"^\s*([\d]+\.%s)\s*(.*)$" % (SESSION_NAME))
|
||||||
|
|
||||||
#how we setup screens status bar
|
# How we setup screens status bar
|
||||||
STATUS_BAR_CMD = r'hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%< %= %H"'
|
STATUS_BAR_CMD = r'hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%< %= %H"'
|
||||||
|
|
||||||
#cmds
|
# Screen commands/template commands
|
||||||
SESSION_INIT = ['screen', '-d', '-m', '-S', SESSION_NAME, '-t', SESSION_DEF_TITLE, '-s', "/bin/bash"]
|
SESSION_INIT = ['screen', '-d', '-m', '-S', SESSION_NAME, '-t', SESSION_DEF_TITLE, '-s', "/bin/bash"]
|
||||||
BAR_INIT = ['screen', '-r', SESSION_NAME, '-X', STATUS_BAR_CMD]
|
BAR_INIT = ['screen', '-r', SESSION_NAME, '-X', STATUS_BAR_CMD]
|
||||||
CMD_INIT = ['screen', '-S', '%SESSION_NAME%', '-X', 'screen', '-t', "%NAME%"]
|
CMD_INIT = ['screen', '-S', '%SESSION_NAME%', '-X', 'screen', '-t', "%NAME%"]
|
||||||
@ -58,17 +58,17 @@ CMD_START = ['screen', '-S', '%SESSION_NAME%', '-p', "%NAME%", '-X', 'stuff', "\
|
|||||||
LIST_CMD = ['screen', '-ls']
|
LIST_CMD = ['screen', '-ls']
|
||||||
SCREEN_KILLER = ['screen', '-X', '-S', '%SCREEN_ID%', 'quit']
|
SCREEN_KILLER = ['screen', '-X', '-S', '%SCREEN_ID%', 'quit']
|
||||||
|
|
||||||
#where our screen sockets will go
|
# Where our screen sockets will go
|
||||||
SCREEN_SOCKET_DIR_NAME = "devstack-screen-sockets"
|
SCREEN_SOCKET_DIR_NAME = "devstack-screen-sockets"
|
||||||
SCREEN_SOCKET_PERM = 0700
|
SCREEN_SOCKET_PERM = 0700
|
||||||
|
|
||||||
#used to wait until started before we can run the actual start cmd
|
# Used to wait until started before we can run the actual start cmd
|
||||||
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
|
||||||
|
|
||||||
#run screen as root?
|
# Run screen as root?
|
||||||
ROOT_GO = True
|
ROOT_GO = True
|
||||||
|
|
||||||
#screen RC file
|
# Screen RC file
|
||||||
SCREEN_RC = settings.RC_FN_TEMPL % ('screen')
|
SCREEN_RC = settings.RC_FN_TEMPL % ('screen')
|
||||||
|
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ class ScreenRunner(base.RunnerBase):
|
|||||||
run_as_root=ROOT_GO,
|
run_as_root=ROOT_GO,
|
||||||
env_overrides=self._get_env(),
|
env_overrides=self._get_env(),
|
||||||
check_exit_code=False)
|
check_exit_code=False)
|
||||||
#we have really no way of knowing if it worked or not, screen sux...
|
# We have really no way of knowing if it worked or not, screen sux...
|
||||||
wipe_cmd = self._gen_cmd(CMD_WIPE, mp)
|
wipe_cmd = self._gen_cmd(CMD_WIPE, mp)
|
||||||
sh.execute(*wipe_cmd,
|
sh.execute(*wipe_cmd,
|
||||||
shell=True,
|
shell=True,
|
||||||
@ -189,7 +189,7 @@ class ScreenRunner(base.RunnerBase):
|
|||||||
shell=True,
|
shell=True,
|
||||||
run_as_root=ROOT_GO,
|
run_as_root=ROOT_GO,
|
||||||
env_overrides=self._get_env())
|
env_overrides=self._get_env())
|
||||||
#we have really no way of knowing if it worked or not, screen sux...
|
# We have really no way of knowing if it worked or not, screen sux...
|
||||||
|
|
||||||
def _do_socketdir_init(self, socketdir, perm):
|
def _do_socketdir_init(self, socketdir, perm):
|
||||||
LOG.debug("Making screen socket directory [%s] (with permissions %o)" % (socketdir, perm))
|
LOG.debug("Making screen socket directory [%s] (with permissions %o)" % (socketdir, perm))
|
||||||
|
@ -26,27 +26,27 @@ from devstack import utils
|
|||||||
|
|
||||||
LOG = logging.getLogger("devstack.runners.upstart")
|
LOG = logging.getLogger("devstack.runners.upstart")
|
||||||
|
|
||||||
#my type
|
# My run type
|
||||||
RUN_TYPE = settings.RUN_TYPE_UPSTART
|
RUN_TYPE = settings.RUN_TYPE_UPSTART
|
||||||
TYPE = settings.RUN_TYPE_TYPE
|
TYPE = settings.RUN_TYPE_TYPE
|
||||||
|
|
||||||
#trace constants
|
# Trace constants
|
||||||
UPSTART_TEMPL = "%s.upstart"
|
UPSTART_TEMPL = "%s.upstart"
|
||||||
ARGS = "ARGS"
|
ARGS = "ARGS"
|
||||||
NAME = "NAME"
|
NAME = "NAME"
|
||||||
|
|
||||||
#upstart event namings
|
# Upstart event namings
|
||||||
START_EVENT_SUFFIX = "_start"
|
START_EVENT_SUFFIX = "_start"
|
||||||
STOP_EVENT_SUFFIX = "_stop"
|
STOP_EVENT_SUFFIX = "_stop"
|
||||||
|
|
||||||
#where upstart configs go
|
# Where upstart configs go
|
||||||
CONF_ROOT = "/etc/init"
|
CONF_ROOT = "/etc/init"
|
||||||
CONF_EXT = ".conf"
|
CONF_EXT = ".conf"
|
||||||
|
|
||||||
#shared template
|
# Shared template
|
||||||
UPSTART_CONF_TMPL = 'upstart.conf'
|
UPSTART_CONF_TMPL = 'upstart.conf'
|
||||||
|
|
||||||
#how we emit events to upstart
|
# How we emit events to upstart
|
||||||
EMIT_BASE_CMD = ["/sbin/initctl", "emit"]
|
EMIT_BASE_CMD = ["/sbin/initctl", "emit"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,28 +15,16 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# These also have meaning outside python,
|
|
||||||
# ie in the pkg/pip listings so update there also!
|
|
||||||
# FIXME: Delete
|
|
||||||
UBUNTU11 = "ubuntu-oneiric"
|
|
||||||
RHEL6 = "rhel-6"
|
|
||||||
FEDORA16 = "fedora-16"
|
|
||||||
|
|
||||||
# What this program is called
|
# What this program is called
|
||||||
PROG_NICE_NAME = "DEVSTACKpy"
|
PROG_NICE_NAME = "DEVSTACKpy"
|
||||||
|
|
||||||
# These 2 identify the json post and pre install sections
|
|
||||||
PRE_INSTALL = 'pre-install'
|
|
||||||
POST_INSTALL = 'post-install'
|
|
||||||
|
|
||||||
# Ip version constants for network ip detection
|
# Ip version constants for network ip detection
|
||||||
IPV4 = 'IPv4'
|
IPV4 = 'IPv4'
|
||||||
IPV6 = 'IPv6'
|
IPV6 = 'IPv6'
|
||||||
|
|
||||||
#how long to wait for a service to startup
|
# How long to wait for a service to startup
|
||||||
WAIT_ALIVE_SECS = 5
|
WAIT_ALIVE_SECS = 5
|
||||||
|
|
||||||
# Component name mappings
|
# Component name mappings
|
||||||
@ -51,7 +39,7 @@ KEYSTONE = "keystone"
|
|||||||
KEYSTONE_CLIENT = 'keystone-client'
|
KEYSTONE_CLIENT = 'keystone-client'
|
||||||
DB = "db"
|
DB = "db"
|
||||||
RABBIT = "rabbit"
|
RABBIT = "rabbit"
|
||||||
NOVNC = 'n-vnc'
|
NOVNC = 'no-vnc'
|
||||||
XVNC = 'xvnc'
|
XVNC = 'xvnc'
|
||||||
MELANGE = 'melange'
|
MELANGE = 'melange'
|
||||||
MELANGE_CLIENT = 'melange-client'
|
MELANGE_CLIENT = 'melange-client'
|
||||||
@ -68,29 +56,6 @@ COMPONENT_NAMES = [
|
|||||||
MELANGE, MELANGE_CLIENT,
|
MELANGE, MELANGE_CLIENT,
|
||||||
]
|
]
|
||||||
|
|
||||||
# When a component is asked for it may
|
|
||||||
# need another component, that dependency
|
|
||||||
# mapping is listed here. A topological sort
|
|
||||||
# will be applied to determine the exact order.
|
|
||||||
# COMPONENT_DEPENDENCIES = {
|
|
||||||
# DB: [],
|
|
||||||
# KEYSTONE_CLIENT: [],
|
|
||||||
# RABBIT: [],
|
|
||||||
# GLANCE: [KEYSTONE, DB],
|
|
||||||
# KEYSTONE: [DB, KEYSTONE_CLIENT],
|
|
||||||
# NOVA: [KEYSTONE, GLANCE, DB, RABBIT, NOVA_CLIENT],
|
|
||||||
# SWIFT: [KEYSTONE_CLIENT],
|
|
||||||
# NOVA_CLIENT: [],
|
|
||||||
# # Horizon depends on glances client (which should really be a client package)
|
|
||||||
# HORIZON: [KEYSTONE_CLIENT, GLANCE, NOVA_CLIENT, QUANTUM_CLIENT],
|
|
||||||
# # More of quantums deps come from its module function get_dependencies
|
|
||||||
# QUANTUM: [],
|
|
||||||
# NOVNC: [NOVA],
|
|
||||||
# QUANTUM_CLIENT: [],
|
|
||||||
# MELANGE: [DB],
|
|
||||||
# MELANGE_CLIENT: [],
|
|
||||||
# }
|
|
||||||
|
|
||||||
# Different run types supported
|
# Different run types supported
|
||||||
RUN_TYPE_FORK = "FORK"
|
RUN_TYPE_FORK = "FORK"
|
||||||
RUN_TYPE_UPSTART = "UPSTART"
|
RUN_TYPE_UPSTART = "UPSTART"
|
||||||
@ -125,7 +90,6 @@ ACTIONS = [INSTALL, UNINSTALL, START, STOP]
|
|||||||
# Where the configs and templates should be at.
|
# Where the configs and templates should be at.
|
||||||
STACK_BIN_DIR = os.path.abspath(os.path.dirname(sys.argv[0]))
|
STACK_BIN_DIR = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||||
STACK_CONFIG_DIR = os.path.join(STACK_BIN_DIR, "conf")
|
STACK_CONFIG_DIR = os.path.join(STACK_BIN_DIR, "conf")
|
||||||
|
STACK_DISTRO_DIR = os.path.join(STACK_CONFIG_DIR, "distros")
|
||||||
STACK_TEMPLATE_DIR = os.path.join(STACK_CONFIG_DIR, "templates")
|
STACK_TEMPLATE_DIR = os.path.join(STACK_CONFIG_DIR, "templates")
|
||||||
STACK_PKG_DIR = os.path.join(STACK_CONFIG_DIR, "pkgs")
|
|
||||||
STACK_PIP_DIR = os.path.join(STACK_CONFIG_DIR, "pips")
|
|
||||||
STACK_CONFIG_LOCATION = os.path.join(STACK_CONFIG_DIR, "stack.ini")
|
STACK_CONFIG_LOCATION = os.path.join(STACK_CONFIG_DIR, "stack.ini")
|
||||||
|
@ -178,11 +178,11 @@ def execute(*cmd, **kwargs):
|
|||||||
raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout, \
|
raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout, \
|
||||||
stderr=stderr, cmd=str_cmd)
|
stderr=stderr, cmd=str_cmd)
|
||||||
else:
|
else:
|
||||||
#log it anyway
|
# Log it anyway
|
||||||
if rc not in check_exit_code:
|
if rc not in check_exit_code:
|
||||||
LOG.debug("A failure may of just happened when running command \"%s\" [%s] (%s, %s)", \
|
LOG.debug("A failure may of just happened when running command \"%s\" [%s] (%s, %s)", \
|
||||||
str_cmd, rc, stdout.strip(), stderr.strip())
|
str_cmd, rc, stdout.strip(), stderr.strip())
|
||||||
#log for debugging figuring stuff out
|
# Log for debugging figuring stuff out
|
||||||
LOG.debug("Received stdout: %s" % (stdout.strip()))
|
LOG.debug("Received stdout: %s" % (stdout.strip()))
|
||||||
LOG.debug("Received stderr: %s" % (stderr.strip()))
|
LOG.debug("Received stderr: %s" % (stderr.strip()))
|
||||||
return (stdout, stderr)
|
return (stdout, stderr)
|
||||||
@ -197,7 +197,7 @@ def abspth(path):
|
|||||||
|
|
||||||
|
|
||||||
def shellquote(text):
|
def shellquote(text):
|
||||||
#TODO since there doesn't seem to be a standard lib that actually works use this way...
|
# TODO since there doesn't seem to be a standard lib that actually works use this way...
|
||||||
do_adjust = False
|
do_adjust = False
|
||||||
for srch in SHELL_QUOTE_REPLACERS.keys():
|
for srch in SHELL_QUOTE_REPLACERS.keys():
|
||||||
if text.find(srch) != -1:
|
if text.find(srch) != -1:
|
||||||
@ -369,16 +369,9 @@ def load_file(fn, quiet=False):
|
|||||||
if not quiet:
|
if not quiet:
|
||||||
LOG.audit("Loading data from file %s", fn)
|
LOG.audit("Loading data from file %s", fn)
|
||||||
data = ""
|
data = ""
|
||||||
try:
|
if not DRYRUN_MODE:
|
||||||
with open(fn, "r") as f:
|
with open(fn, "r") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
except IOError as e:
|
|
||||||
if DRYRUN_MODE:
|
|
||||||
# We still need to actually load something (ie the json install files so thats)
|
|
||||||
# Why this is in the exception path.
|
|
||||||
LOG.audit("Passing on load exception since in dry-run mode")
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
LOG.audit("Loaded (%d) bytes from file %s", len(data), fn)
|
LOG.audit("Loaded (%d) bytes from file %s", len(data), fn)
|
||||||
return data
|
return data
|
||||||
@ -500,16 +493,16 @@ def create_loopback_file(fname, size, bsize=1024, fs_type='ext3', run_as_root=Fa
|
|||||||
'count=0', 'seek=%d' % size]
|
'count=0', 'seek=%d' % size]
|
||||||
mkfs_cmd = ['mkfs.%s' % fs_type, '-f', '-i', 'size=%d' % bsize, fname]
|
mkfs_cmd = ['mkfs.%s' % fs_type, '-f', '-i', 'size=%d' % bsize, fname]
|
||||||
|
|
||||||
# make sure folder exists
|
# Make sure folder exists
|
||||||
files = mkdirslist(dirname(fname))
|
files = mkdirslist(dirname(fname))
|
||||||
|
|
||||||
# create file
|
# Create file
|
||||||
touch_file(fname)
|
touch_file(fname)
|
||||||
|
|
||||||
# fill with zeroes
|
# Fill with zeroes
|
||||||
execute(*dd_cmd, run_as_root=run_as_root)
|
execute(*dd_cmd, run_as_root=run_as_root)
|
||||||
|
|
||||||
# create fs on the file
|
# Create fs on the file
|
||||||
execute(*mkfs_cmd, run_as_root=run_as_root)
|
execute(*mkfs_cmd, run_as_root=run_as_root)
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
@ -15,16 +15,17 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from devstack import date
|
from devstack import date
|
||||||
from devstack import exceptions as excp
|
from devstack import exceptions as excp
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
|
|
||||||
#trace per line output and file extension formats
|
# Trace per line output format and file extension formats
|
||||||
TRACE_FMT = "%s - %s\n"
|
TRACE_FMT = ("%s - %s" + os.linesep)
|
||||||
TRACE_EXT = ".trace"
|
TRACE_EXT = ".trace"
|
||||||
|
|
||||||
#common trace actions
|
# Common trace actions
|
||||||
CFG_WRITING_FILE = "CFG_WRITING_FILE"
|
CFG_WRITING_FILE = "CFG_WRITING_FILE"
|
||||||
SYMLINK_MAKE = "SYMLINK_MAKE"
|
SYMLINK_MAKE = "SYMLINK_MAKE"
|
||||||
PKG_INSTALL = "PKG_INSTALL"
|
PKG_INSTALL = "PKG_INSTALL"
|
||||||
@ -35,12 +36,12 @@ DOWNLOADED = "DOWNLOADED"
|
|||||||
AP_STARTED = "AP_STARTED"
|
AP_STARTED = "AP_STARTED"
|
||||||
PIP_INSTALL = 'PIP_INSTALL'
|
PIP_INSTALL = 'PIP_INSTALL'
|
||||||
|
|
||||||
#trace file types
|
# Common trace file types (or the expected common ones)
|
||||||
PY_TRACE = "python"
|
PY_TRACE = "python"
|
||||||
IN_TRACE = "install"
|
IN_TRACE = "install"
|
||||||
START_TRACE = "start"
|
START_TRACE = "start"
|
||||||
|
|
||||||
#used to note version of trace
|
# Used to note version of trace
|
||||||
TRACE_VERSION = "TRACE_VERSION"
|
TRACE_VERSION = "TRACE_VERSION"
|
||||||
TRACE_VER = 0x1
|
TRACE_VER = 0x1
|
||||||
|
|
||||||
@ -95,12 +96,9 @@ class TraceWriter(object):
|
|||||||
what['from'] = uri
|
what['from'] = uri
|
||||||
self.trace(DOWNLOADED, json.dumps(what))
|
self.trace(DOWNLOADED, json.dumps(what))
|
||||||
|
|
||||||
def pip_installed(self, name, pip_info):
|
def pip_installed(self, pip_info):
|
||||||
self._start()
|
self._start()
|
||||||
what = dict()
|
self.trace(PIP_INSTALL, json.dumps(pip_info))
|
||||||
what['name'] = name
|
|
||||||
what['pip_meta'] = pip_info
|
|
||||||
self.trace(PIP_INSTALL, json.dumps(what))
|
|
||||||
|
|
||||||
def dirs_made(self, *dirs):
|
def dirs_made(self, *dirs):
|
||||||
self._start()
|
self._start()
|
||||||
@ -111,12 +109,9 @@ class TraceWriter(object):
|
|||||||
self._start()
|
self._start()
|
||||||
self.trace(FILE_TOUCHED, fn)
|
self.trace(FILE_TOUCHED, fn)
|
||||||
|
|
||||||
def package_installed(self, name, pkg_info):
|
def package_installed(self, pkg_info):
|
||||||
self._start()
|
self._start()
|
||||||
what = dict()
|
self.trace(PKG_INSTALL, json.dumps(pkg_info))
|
||||||
what['name'] = name
|
|
||||||
what['pkg_meta'] = pkg_info
|
|
||||||
self.trace(PKG_INSTALL, json.dumps(what))
|
|
||||||
|
|
||||||
def started_info(self, name, info_fn):
|
def started_info(self, name, info_fn):
|
||||||
self._start()
|
self._start()
|
||||||
@ -187,7 +182,7 @@ class TraceReader(object):
|
|||||||
return locations
|
return locations
|
||||||
|
|
||||||
def _sort_paths(self, pths):
|
def _sort_paths(self, pths):
|
||||||
#ensure in ok order (ie /tmp is before /)
|
# Ensure in correct order (ie /tmp is before /)
|
||||||
pths = list(set(pths))
|
pths = list(set(pths))
|
||||||
pths.sort()
|
pths.sort()
|
||||||
pths.reverse()
|
pths.reverse()
|
||||||
@ -221,14 +216,11 @@ class TraceReader(object):
|
|||||||
|
|
||||||
def symlinks_made(self):
|
def symlinks_made(self):
|
||||||
lines = self.read()
|
lines = self.read()
|
||||||
files = list()
|
links = list()
|
||||||
for (cmd, action) in lines:
|
for (cmd, action) in lines:
|
||||||
if cmd == SYMLINK_MAKE and len(action):
|
if cmd == SYMLINK_MAKE and len(action):
|
||||||
files.append(action)
|
links.append(action)
|
||||||
#ensure in ok order (ie /tmp is before /)
|
return links
|
||||||
files.sort()
|
|
||||||
files.reverse()
|
|
||||||
return files
|
|
||||||
|
|
||||||
def files_configured(self):
|
def files_configured(self):
|
||||||
lines = self.read()
|
lines = self.read()
|
||||||
@ -242,7 +234,7 @@ class TraceReader(object):
|
|||||||
|
|
||||||
def pips_installed(self):
|
def pips_installed(self):
|
||||||
lines = self.read()
|
lines = self.read()
|
||||||
pips_installed = dict()
|
pips_installed = list()
|
||||||
pip_list = list()
|
pip_list = list()
|
||||||
for (cmd, action) in lines:
|
for (cmd, action) in lines:
|
||||||
if cmd == PIP_INSTALL and len(action):
|
if cmd == PIP_INSTALL and len(action):
|
||||||
@ -250,14 +242,12 @@ class TraceReader(object):
|
|||||||
for pip_data in pip_list:
|
for pip_data in pip_list:
|
||||||
pip_info_full = json.loads(pip_data)
|
pip_info_full = json.loads(pip_data)
|
||||||
if type(pip_info_full) is dict:
|
if type(pip_info_full) is dict:
|
||||||
name = pip_info_full.get('name')
|
pips_installed.append(pip_info_full)
|
||||||
if name:
|
|
||||||
pips_installed[name] = pip_info_full.get('pip_meta')
|
|
||||||
return pips_installed
|
return pips_installed
|
||||||
|
|
||||||
def packages_installed(self):
|
def packages_installed(self):
|
||||||
lines = self.read()
|
lines = self.read()
|
||||||
pkgs_installed = dict()
|
pkgs_installed = list()
|
||||||
pkg_list = list()
|
pkg_list = list()
|
||||||
for (cmd, action) in lines:
|
for (cmd, action) in lines:
|
||||||
if cmd == PKG_INSTALL and len(action):
|
if cmd == PKG_INSTALL and len(action):
|
||||||
@ -265,7 +255,5 @@ class TraceReader(object):
|
|||||||
for pkg_data in pkg_list:
|
for pkg_data in pkg_list:
|
||||||
pkg_info = json.loads(pkg_data)
|
pkg_info = json.loads(pkg_data)
|
||||||
if type(pkg_info) is dict:
|
if type(pkg_info) is dict:
|
||||||
name = pkg_info.get('name')
|
pkgs_installed.append(pkg_info)
|
||||||
if name:
|
|
||||||
pkgs_installed[name] = pkg_info.get('pkg_meta')
|
|
||||||
return pkgs_installed
|
return pkgs_installed
|
||||||
|
@ -21,7 +21,6 @@ import distutils.version
|
|||||||
import json
|
import json
|
||||||
import netifaces
|
import netifaces
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
@ -51,7 +50,8 @@ ALL_NUMS = re.compile(r"^\d+$")
|
|||||||
START_NUMS = re.compile(r"^(\d+)(\D+)")
|
START_NUMS = re.compile(r"^(\d+)(\D+)")
|
||||||
STAR_VERSION = 0
|
STAR_VERSION = 0
|
||||||
|
|
||||||
#thx cowsay
|
# Thx cowsay
|
||||||
|
# See: http://www.nog.net/~tony/warez/cowsay.shtml
|
||||||
COWS = dict()
|
COWS = dict()
|
||||||
COWS['happy'] = r'''
|
COWS['happy'] = r'''
|
||||||
{header}
|
{header}
|
||||||
@ -139,12 +139,15 @@ def to_bytes(text):
|
|||||||
return byte_val
|
return byte_val
|
||||||
|
|
||||||
|
|
||||||
def import_module(module_name):
|
def import_module(module_name, quiet=True):
|
||||||
try:
|
try:
|
||||||
__import__(module_name)
|
__import__(module_name)
|
||||||
return sys.modules.get(module_name, None)
|
return sys.modules.get(module_name, None)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
return None
|
if quiet:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def load_json(fn):
|
def load_json(fn):
|
||||||
@ -206,6 +209,8 @@ def get_host_ip():
|
|||||||
were to be sent out to some well known address on the Internet. In this
|
were to be sent out to some well known address on the Internet. In this
|
||||||
case, a private address is used, but the specific address does not
|
case, a private address is used, but the specific address does not
|
||||||
matter much. No traffic is actually sent.
|
matter much. No traffic is actually sent.
|
||||||
|
|
||||||
|
Adjusted from nova code...
|
||||||
"""
|
"""
|
||||||
ip = None
|
ip = None
|
||||||
try:
|
try:
|
||||||
@ -216,7 +221,7 @@ def get_host_ip():
|
|||||||
ip = addr
|
ip = addr
|
||||||
except socket.error:
|
except socket.error:
|
||||||
pass
|
pass
|
||||||
#attempt to find it
|
# Ettempt to find it
|
||||||
if not ip:
|
if not ip:
|
||||||
interfaces = get_interfaces()
|
interfaces = get_interfaces()
|
||||||
for (_, net_info) in interfaces.items():
|
for (_, net_info) in interfaces.items():
|
||||||
@ -227,7 +232,7 @@ def get_host_ip():
|
|||||||
if first_oct and first_oct not in PRIVATE_OCTS:
|
if first_oct and first_oct not in PRIVATE_OCTS:
|
||||||
ip = a_ip
|
ip = a_ip
|
||||||
break
|
break
|
||||||
#just return a localhost version then
|
# Just return a localhost version then
|
||||||
if not ip:
|
if not ip:
|
||||||
ip = DEF_IP
|
ip = DEF_IP
|
||||||
return ip
|
return ip
|
||||||
@ -246,90 +251,21 @@ def get_interfaces():
|
|||||||
interface_addresses = netifaces.ifaddresses(intfc)
|
interface_addresses = netifaces.ifaddresses(intfc)
|
||||||
ip6 = interface_addresses.get(netifaces.AF_INET6)
|
ip6 = interface_addresses.get(netifaces.AF_INET6)
|
||||||
if ip6 and len(ip6):
|
if ip6 and len(ip6):
|
||||||
#just take the first
|
# Just take the first
|
||||||
interface_info[settings.IPV6] = ip6[0]
|
interface_info[settings.IPV6] = ip6[0]
|
||||||
ip4 = interface_addresses.get(netifaces.AF_INET)
|
ip4 = interface_addresses.get(netifaces.AF_INET)
|
||||||
if ip4 and len(ip4):
|
if ip4 and len(ip4):
|
||||||
#just take the first
|
# Just take the first
|
||||||
interface_info[settings.IPV4] = ip4[0]
|
interface_info[settings.IPV4] = ip4[0]
|
||||||
#there are others but this is good for now
|
# Note: there are others but this is good for now..
|
||||||
interfaces[intfc] = interface_info
|
interfaces[intfc] = interface_info
|
||||||
return interfaces
|
return interfaces
|
||||||
|
|
||||||
|
|
||||||
def get_components_order(components):
|
def format_secs_taken(secs):
|
||||||
if not components:
|
output = "%.03f seconds" % (secs)
|
||||||
return dict()
|
output += " or %.02f minutes" % (secs / 60.0)
|
||||||
#deep copy so components isn't messed with
|
return output
|
||||||
all_components = dict()
|
|
||||||
for (name, deps) in components.items():
|
|
||||||
all_components[name] = set(deps)
|
|
||||||
#figure out which ones have no one depending on them
|
|
||||||
no_deps_components = set()
|
|
||||||
for (name, deps) in all_components.items():
|
|
||||||
referenced = False
|
|
||||||
for (_name, _deps) in all_components.items():
|
|
||||||
if _name == name:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if name in _deps:
|
|
||||||
referenced = True
|
|
||||||
break
|
|
||||||
if not referenced:
|
|
||||||
no_deps_components.add(name)
|
|
||||||
if not no_deps_components:
|
|
||||||
msg = "Components specifed have no root components, there is most likely a dependency cycle!"
|
|
||||||
raise excp.DependencyException(msg)
|
|
||||||
#now we have to do a quick check to ensure no component is causing a cycle
|
|
||||||
for (root, deps) in all_components.items():
|
|
||||||
#DFS down through the "roots" deps and there deps and so on and
|
|
||||||
#ensure that nobody is referencing the "root" component name,
|
|
||||||
#that would mean there is a cycle if a dependency of the "root" is.
|
|
||||||
active_deps = list(deps)
|
|
||||||
checked_deps = dict()
|
|
||||||
while len(active_deps):
|
|
||||||
dep = active_deps.pop()
|
|
||||||
itsdeps = all_components.get(dep)
|
|
||||||
checked_deps[dep] = True
|
|
||||||
if root in itsdeps:
|
|
||||||
msg = "Circular dependency between component %s and component %s!" % (root, dep)
|
|
||||||
raise excp.DependencyException(msg)
|
|
||||||
else:
|
|
||||||
for d in itsdeps:
|
|
||||||
if d not in checked_deps and d not in active_deps:
|
|
||||||
active_deps.append(d)
|
|
||||||
#now form the order
|
|
||||||
#basically a topological sorting
|
|
||||||
#https://en.wikipedia.org/wiki/Topological_sorting
|
|
||||||
ordering = list()
|
|
||||||
no_edges = set(no_deps_components)
|
|
||||||
while len(no_edges):
|
|
||||||
node = no_edges.pop()
|
|
||||||
ordering.append(node)
|
|
||||||
its_deps = all_components.get(node)
|
|
||||||
while len(its_deps):
|
|
||||||
name = its_deps.pop()
|
|
||||||
referenced = False
|
|
||||||
for (_name, _deps) in all_components.items():
|
|
||||||
if _name == name:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if name in _deps:
|
|
||||||
referenced = True
|
|
||||||
break
|
|
||||||
if not referenced:
|
|
||||||
no_edges.add(name)
|
|
||||||
#should now be no edges else something bad happended
|
|
||||||
for (_, deps) in all_components.items():
|
|
||||||
if len(deps):
|
|
||||||
msg = "Your specified components have at least one cycle!"
|
|
||||||
raise excp.DependencyException(msg)
|
|
||||||
#reverse so its in the right order for us since we just determined
|
|
||||||
#the pkgs that have no one depending on them (which should be installed
|
|
||||||
#last and those that have incoming edges that packages are depending on need
|
|
||||||
#to go first, but those were inserted last), so this reverse fixes that
|
|
||||||
ordering.reverse()
|
|
||||||
return ordering
|
|
||||||
|
|
||||||
|
|
||||||
def joinlinesep(*pieces):
|
def joinlinesep(*pieces):
|
||||||
@ -418,7 +354,8 @@ def param_replace(text, replacements, ignore_missing=False):
|
|||||||
|
|
||||||
def _get_welcome_stack():
|
def _get_welcome_stack():
|
||||||
possibles = list()
|
possibles = list()
|
||||||
#thank you figlet ;)
|
# Thank you figlet ;)
|
||||||
|
# See: http://www.figlet.org/
|
||||||
possibles.append(r'''
|
possibles.append(r'''
|
||||||
___ ____ _____ _ _ ____ _____ _ ____ _ __
|
___ ____ _____ _ _ ____ _____ _ ____ _ __
|
||||||
/ _ \| _ \| ____| \ | / ___|_ _|/ \ / ___| |/ /
|
/ _ \| _ \| ____| \ | / ___|_ _|/ \ / ___| |/ /
|
||||||
@ -474,7 +411,7 @@ def center_text(text, fill, max_len):
|
|||||||
def _welcome_slang():
|
def _welcome_slang():
|
||||||
potentials = list()
|
potentials = list()
|
||||||
potentials.append("And now for something completely different!")
|
potentials.append("And now for something completely different!")
|
||||||
return random.choice(potentials).strip("\n\r")
|
return random.choice(potentials)
|
||||||
|
|
||||||
|
|
||||||
def color_text(text, color, bold=False,
|
def color_text(text, color, bold=False,
|
||||||
@ -503,7 +440,8 @@ def _color_blob(text, text_color):
|
|||||||
|
|
||||||
|
|
||||||
def _goodbye_header(worked):
|
def _goodbye_header(worked):
|
||||||
#cowsay headers
|
# Cowsay headers
|
||||||
|
# See: http://www.nog.net/~tony/warez/cowsay.shtml
|
||||||
potentials_oks = list()
|
potentials_oks = list()
|
||||||
potentials_oks.append(r'''
|
potentials_oks.append(r'''
|
||||||
___________
|
___________
|
||||||
@ -707,28 +645,6 @@ def goodbye(worked):
|
|||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
|
|
||||||
def parse_components(components):
|
|
||||||
if not components:
|
|
||||||
return dict()
|
|
||||||
adjusted_components = dict()
|
|
||||||
for c in components:
|
|
||||||
mtch = EXT_COMPONENT.match(c)
|
|
||||||
if mtch:
|
|
||||||
component_name = mtch.group(1).lower().strip()
|
|
||||||
if component_name in settings.COMPONENT_NAMES:
|
|
||||||
component_opts = mtch.group(2)
|
|
||||||
components_opts_cleaned = None
|
|
||||||
if component_opts:
|
|
||||||
components_opts_cleaned = list()
|
|
||||||
sp_component_opts = component_opts.split(",")
|
|
||||||
for co in sp_component_opts:
|
|
||||||
cleaned_opt = co.strip()
|
|
||||||
if cleaned_opt:
|
|
||||||
components_opts_cleaned.append(cleaned_opt)
|
|
||||||
adjusted_components[component_name] = components_opts_cleaned
|
|
||||||
return adjusted_components
|
|
||||||
|
|
||||||
|
|
||||||
def welcome(ident):
|
def welcome(ident):
|
||||||
lower = "| %s %s |" % (ident, version.version_string())
|
lower = "| %s %s |" % (ident, version.version_string())
|
||||||
welcome_header = _get_welcome_stack()
|
welcome_header = _get_welcome_stack()
|
||||||
@ -738,8 +654,8 @@ def welcome(ident):
|
|||||||
footer += color_text(lower, 'blue', True)
|
footer += color_text(lower, 'blue', True)
|
||||||
uncolored_footer = (settings.PROG_NICE_NAME + ": " + lower)
|
uncolored_footer = (settings.PROG_NICE_NAME + ": " + lower)
|
||||||
if max_line_len - len(uncolored_footer) > 0:
|
if max_line_len - len(uncolored_footer) > 0:
|
||||||
#this format string will center the uncolored text which
|
# This format string will center the uncolored text which
|
||||||
#we will then replace with the color text equivalent
|
# we will then replace with the color text equivalent.
|
||||||
centered_str = center_text(uncolored_footer, " ", max_line_len)
|
centered_str = center_text(uncolored_footer, " ", max_line_len)
|
||||||
footer = centered_str.replace(uncolored_footer, footer)
|
footer = centered_str.replace(uncolored_footer, footer)
|
||||||
print(welcome_header)
|
print(welcome_header)
|
||||||
|
63
stack
63
stack
@ -20,6 +20,7 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from devstack import cfg
|
||||||
from devstack import cfg_helpers
|
from devstack import cfg_helpers
|
||||||
from devstack import date
|
from devstack import date
|
||||||
from devstack import distro
|
from devstack import distro
|
||||||
@ -27,13 +28,11 @@ from devstack import env
|
|||||||
from devstack import env_rc
|
from devstack import env_rc
|
||||||
from devstack import log as logging
|
from devstack import log as logging
|
||||||
from devstack import opts
|
from devstack import opts
|
||||||
from devstack import passwords
|
|
||||||
from devstack import settings
|
from devstack import settings
|
||||||
from devstack import shell as sh
|
from devstack import shell as sh
|
||||||
from devstack import utils
|
from devstack import utils
|
||||||
|
|
||||||
from devstack.progs import actions
|
from devstack.progs import actions
|
||||||
from devstack.progs import common
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger("devstack.stack")
|
LOG = logging.getLogger("devstack.stack")
|
||||||
@ -50,7 +49,7 @@ _WELCOME_MAP = {
|
|||||||
_CFG_GROUPS = {
|
_CFG_GROUPS = {
|
||||||
cfg_helpers.make_id('passwords', None): 'Passwords',
|
cfg_helpers.make_id('passwords', None): 'Passwords',
|
||||||
cfg_helpers.make_id('db', None): 'Database info',
|
cfg_helpers.make_id('db', None): 'Database info',
|
||||||
#catch all
|
# Catch all
|
||||||
cfg_helpers.make_id(None, None): 'Misc configs',
|
cfg_helpers.make_id(None, None): 'Misc configs',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +67,12 @@ def dump_config(config_cache):
|
|||||||
value = mp.get(key)
|
value = mp.get(key)
|
||||||
LOG.info(item_format(key, value))
|
LOG.info(item_format(key, value))
|
||||||
|
|
||||||
#first partition into our groups
|
# First partition into our groups
|
||||||
partitions = dict()
|
partitions = dict()
|
||||||
for name in _CFG_ORDERING:
|
for name in _CFG_ORDERING:
|
||||||
partitions[name] = dict()
|
partitions[name] = dict()
|
||||||
|
|
||||||
#now put the config cached values into there partition
|
# Now put the config cached values into there partitions
|
||||||
for (k, v) in config_cache.items():
|
for (k, v) in config_cache.items():
|
||||||
for name in _CFG_ORDERING:
|
for name in _CFG_ORDERING:
|
||||||
entries = partitions[name]
|
entries = partitions[name]
|
||||||
@ -81,7 +80,7 @@ def dump_config(config_cache):
|
|||||||
entries[k] = v
|
entries[k] = v
|
||||||
break
|
break
|
||||||
|
|
||||||
#now print them..
|
# Now print them..
|
||||||
for name in _CFG_ORDERING:
|
for name in _CFG_ORDERING:
|
||||||
nice_name = _CFG_GROUPS.get(name)
|
nice_name = _CFG_GROUPS.get(name)
|
||||||
LOG.info(nice_name + ":")
|
LOG.info(nice_name + ":")
|
||||||
@ -103,49 +102,55 @@ def load_rc_files():
|
|||||||
|
|
||||||
|
|
||||||
def run(args):
|
def run(args):
|
||||||
action = args.pop("action").strip().lower()
|
action = args.pop("action", '').strip().lower()
|
||||||
if not (action in settings.ACTIONS):
|
if not (action in settings.ACTIONS):
|
||||||
print(utils.color_text("No valid action specified!", "red"))
|
print(utils.color_text("No valid action specified!", "red"))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
loaded_rcs = False
|
loaded_rcs = False
|
||||||
rootdir = args.pop("dir")
|
root_dir = args.pop("dir")
|
||||||
if not rootdir:
|
if not root_dir:
|
||||||
load_rc_files()
|
load_rc_files()
|
||||||
loaded_rcs = True
|
loaded_rcs = True
|
||||||
rootdir = env.get_key(env_rc.INSTALL_ROOT)
|
root_dir = env.get_key(env_rc.INSTALL_ROOT)
|
||||||
if not rootdir:
|
if not root_dir:
|
||||||
print(utils.color_text("No root directory specified!", "red"))
|
print(utils.color_text("No root directory specified!", "red"))
|
||||||
return False
|
return False
|
||||||
|
root_dir = sh.abspth(root_dir)
|
||||||
|
|
||||||
#welcome!
|
persona_fn = args.pop('persona_fn')
|
||||||
|
if not persona_fn or not sh.isfile(persona_fn):
|
||||||
|
print(utils.color_text("No valid persona file name specified!", "red"))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Welcome!
|
||||||
(repeat_string, line_max_len) = utils.welcome(_WELCOME_MAP.get(action))
|
(repeat_string, line_max_len) = utils.welcome(_WELCOME_MAP.get(action))
|
||||||
print(utils.center_text("Action Runner", repeat_string, line_max_len))
|
print(utils.center_text("Action Runner", repeat_string, line_max_len))
|
||||||
|
|
||||||
#here on out we should be using the logger (and not print)
|
# !!
|
||||||
start_time = time.time()
|
# Here on out we should be using the logger (and not print)!!
|
||||||
|
# !!
|
||||||
|
|
||||||
# if we didn't load them before, load them now
|
# If we didn't load them before, load them now
|
||||||
if not loaded_rcs:
|
if not loaded_rcs:
|
||||||
load_rc_files()
|
load_rc_files()
|
||||||
loaded_rcs = True
|
loaded_rcs = True
|
||||||
|
|
||||||
# Stash the dryrun value (if any) into the global configuration
|
# Stash the dryrun value (if any) into the global configuration
|
||||||
sh.set_dryrun(args['dryrun'])
|
sh.set_dryrun(args.pop('dryrun'))
|
||||||
|
|
||||||
dist = distro.Distro.get_current()
|
dist = distro.Distro.get_current()
|
||||||
config = common.get_config()
|
config = cfg.get_config()
|
||||||
pw_gen = passwords.PasswordGenerator(config, args['prompt_for_passwords'])
|
runner = actions.ActionRunner(dist, action, config, **args)
|
||||||
pkg_factory = dist.get_packager_factory()
|
|
||||||
pkg_manager = pkg_factory(dist, args['keep_old'])
|
|
||||||
|
|
||||||
components = utils.parse_components(args.pop("components"))
|
|
||||||
runner = actions.ActionRunner(dist, action, rootdir, config, pw_gen,
|
|
||||||
pkg_manager, components=components, **args)
|
|
||||||
|
|
||||||
LOG.info("Starting action [%s] on %s for distro [%s]" % (action, date.rcf8222date(), dist))
|
LOG.info("Starting action [%s] on %s for distro [%s]" % (action, date.rcf8222date(), dist))
|
||||||
runner.run()
|
|
||||||
LOG.info("It took (%s) to complete action [%s]" % (common.format_secs_taken((time.time() - start_time)), action))
|
start_time = time.time()
|
||||||
|
runner.run(persona_fn, root_dir)
|
||||||
|
end_time = time.time()
|
||||||
|
|
||||||
|
LOG.info("It took (%s) to complete action [%s]" %
|
||||||
|
(utils.format_secs_taken((end_time - start_time)), action))
|
||||||
LOG.info("After action [%s] your settings which were created or read are:" % (action))
|
LOG.info("After action [%s] your settings which were created or read are:" % (action))
|
||||||
|
|
||||||
dump_config(config.configs_fetched)
|
dump_config(config.configs_fetched)
|
||||||
@ -154,7 +159,7 @@ def run(args):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
#do this first so people can see the help message...
|
# Do this first so people can see the help message...
|
||||||
args = opts.parse()
|
args = opts.parse()
|
||||||
prog_name = sys.argv[0]
|
prog_name = sys.argv[0]
|
||||||
|
|
||||||
@ -163,7 +168,7 @@ def main():
|
|||||||
|
|
||||||
LOG.debug("Command line options %s" % (args))
|
LOG.debug("Command line options %s" % (args))
|
||||||
|
|
||||||
#will need root to setup openstack
|
# Will need root to setup openstack
|
||||||
if not sh.got_root():
|
if not sh.got_root():
|
||||||
rest_args = sys.argv[1:]
|
rest_args = sys.argv[1:]
|
||||||
print("This program requires a user with sudo access.")
|
print("This program requires a user with sudo access.")
|
||||||
@ -173,7 +178,7 @@ def main():
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
#drop to usermode
|
# Drop to usermode
|
||||||
sh.user_mode(False)
|
sh.user_mode(False)
|
||||||
started_ok = run(args)
|
started_ok = run(args)
|
||||||
if not started_ok:
|
if not started_ok:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user