Merge branch 'master' into feature/zuulv3
Change-Id: I5d16c217bd4264ab22daa26103e1e293ca8bb684
This commit is contained in:
commit
5d9bdd4d3a
14
README.rst
14
README.rst
@ -7,14 +7,20 @@ of devstack images on a cloud server for use in OpenStack project testing.
|
||||
Developer setup
|
||||
===============
|
||||
|
||||
Make sure you have pip installed:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
|
||||
Install dependencies:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get -qy install git mysql-server libmysqlclient-dev g++\
|
||||
python-dev python-pip libffi-dev libssl-dev qemu-utils\
|
||||
libxml2-dev libxslt1-dev python-lxml
|
||||
sudo pip install bindep
|
||||
sudo apt-get install $(bindep -b nodepool)
|
||||
|
||||
mkdir src
|
||||
cd ~/src
|
||||
git clone git://git.openstack.org/openstack-infra/system-config
|
||||
|
@ -199,8 +199,8 @@ labels:
|
||||
min-ready: 1
|
||||
providers:
|
||||
- name: devstack
|
||||
- name: fedora-24
|
||||
image: fedora-24
|
||||
- name: fedora-25
|
||||
image: fedora-25
|
||||
min-ready: 1
|
||||
providers:
|
||||
- name: devstack
|
||||
@ -228,31 +228,36 @@ providers:
|
||||
# Long boot timeout to deal with potentially nested virt.
|
||||
boot-timeout: 600
|
||||
launch-timeout: 900
|
||||
max-servers: 2
|
||||
max-servers: 5
|
||||
rate: 0.25
|
||||
images:
|
||||
- name: centos-7
|
||||
min-ram: 1024
|
||||
name-filter: 'nodepool'
|
||||
username: devuser
|
||||
private-key: $NODEPOOL_KEY
|
||||
config-drive: true
|
||||
- name: fedora-24
|
||||
- name: fedora-25
|
||||
min-ram: 1024
|
||||
name-filter: 'nodepool'
|
||||
username: devuser
|
||||
private-key: $NODEPOOL_KEY
|
||||
config-drive: true
|
||||
- name: ubuntu-precise
|
||||
min-ram: 1024
|
||||
min-ram: 512
|
||||
name-filter: 'nodepool'
|
||||
username: devuser
|
||||
private-key: $NODEPOOL_KEY
|
||||
config-drive: true
|
||||
- name: ubuntu-trusty
|
||||
min-ram: 1024
|
||||
min-ram: 512
|
||||
name-filter: 'nodepool'
|
||||
username: devuser
|
||||
private-key: $NODEPOOL_KEY
|
||||
config-drive: true
|
||||
- name: ubuntu-xenial
|
||||
min-ram: 1024
|
||||
min-ram: 512
|
||||
name-filter: 'nodepool'
|
||||
username: devuser
|
||||
private-key: $NODEPOOL_KEY
|
||||
config-drive: true
|
||||
@ -277,8 +282,8 @@ diskimages:
|
||||
$DIB_GLEAN_INSTALLTYPE
|
||||
$DIB_GLEAN_REPOLOCATION
|
||||
$DIB_GLEAN_REPOREF
|
||||
- name: fedora-24
|
||||
pause: $NODEPOOL_PAUSE_FEDORA_24_DIB
|
||||
- name: fedora-25
|
||||
pause: $NODEPOOL_PAUSE_FEDORA_25_DIB
|
||||
rebuild-age: 86400
|
||||
elements:
|
||||
- fedora-minimal
|
||||
@ -287,7 +292,7 @@ diskimages:
|
||||
- devuser
|
||||
- openssh-server
|
||||
- nodepool-setup
|
||||
release: 24
|
||||
release: 25
|
||||
env-vars:
|
||||
TMPDIR: $NODEPOOL_DIB_BASE_PATH/tmp
|
||||
DIB_CHECKSUM: '1'
|
||||
@ -399,8 +404,11 @@ function configure_nodepool {
|
||||
function start_nodepool {
|
||||
# build a custom flavor that's more friendly to nodepool
|
||||
local available_flavors=$(nova flavor-list)
|
||||
if [[ ! ( $available_flavors =~ 'm1.nodepool' ) ]]; then
|
||||
nova flavor-create m1.nodepool 64 1024 0 1
|
||||
if [[ ! ( $available_flavors =~ 'nodepool-512' ) ]]; then
|
||||
nova flavor-create nodepool-512 64 512 0 1
|
||||
fi
|
||||
if [[ ! ( $available_flavors =~ 'nodepool-1024' ) ]]; then
|
||||
nova flavor-create nodepool-1024 128 1024 0 1
|
||||
fi
|
||||
|
||||
# build sec group rules to reach the nodes, we need to do this
|
||||
|
@ -229,6 +229,30 @@ Example configuration::
|
||||
DIB_APT_LOCAL_CACHE: '0'
|
||||
DIB_DISABLE_APT_CLEANUP: '1'
|
||||
FS_TYPE: ext3
|
||||
- name: ubuntu-xenial
|
||||
pause: True
|
||||
rebuild-age: 86400
|
||||
formats:
|
||||
- raw
|
||||
- tar
|
||||
elements:
|
||||
- ubuntu-minimal
|
||||
- vm
|
||||
- simple-init
|
||||
- openstack-repos
|
||||
- nodepool-base
|
||||
- cache-devstack
|
||||
- cache-bindep
|
||||
- growroot
|
||||
- infra-package-needs
|
||||
release: precise
|
||||
env-vars:
|
||||
TMPDIR: /opt/dib_tmp
|
||||
DIB_CHECKSUM: '1'
|
||||
DIB_IMAGE_CACHE: /opt/dib_cache
|
||||
DIB_APT_LOCAL_CACHE: '0'
|
||||
DIB_DISABLE_APT_CLEANUP: '1'
|
||||
FS_TYPE: ext3
|
||||
|
||||
|
||||
**required**
|
||||
@ -238,6 +262,12 @@ Example configuration::
|
||||
|
||||
**optional**
|
||||
|
||||
``formats`` (list)
|
||||
The list of formats to build is normally automatically created based on the
|
||||
needs of the providers to which the image is uploaded. To build images even
|
||||
when no providers are configured or to build additional formats which you
|
||||
know you may need in the future, list those formats here.
|
||||
|
||||
``rebuild-age``
|
||||
If the current diskimage is older than this value (in seconds),
|
||||
then nodepool will attempt to rebuild it. Defaults to 86400 (24
|
||||
@ -279,11 +309,9 @@ provider, the Nodepool image types are also defined (see
|
||||
boot-timeout: 120
|
||||
launch-timeout: 900
|
||||
template-hostname: 'template-{image.name}-{timestamp}'
|
||||
pool: 'public'
|
||||
ipv6-preferred: False
|
||||
networks:
|
||||
- name: 'some-network-name'
|
||||
public: True
|
||||
images:
|
||||
- name: trusty
|
||||
min-ram: 8192
|
||||
@ -400,9 +428,7 @@ provider, the Nodepool image types are also defined (see
|
||||
|
||||
``networks`` (dict)
|
||||
Specify custom Neutron networks that get attached to each
|
||||
node. Specify the ``name`` of the network (a string) and if the
|
||||
network routes to the Internet, set the boolean ``public`` to
|
||||
true.
|
||||
node. Specify the ``name`` of the network (a string).
|
||||
|
||||
``ipv6-preferred``
|
||||
If it is set to True, nodepool will try to find ipv6 in public net first
|
||||
@ -410,10 +436,6 @@ provider, the Nodepool image types are also defined (see
|
||||
jenkins slave definition. If ipv6 is not found or the key is not
|
||||
specified or set to False, ipv4 address will be used.
|
||||
|
||||
``pool``
|
||||
Specify a floating ip pool in cases where the 'public' pool is unavailable
|
||||
or undesirable.
|
||||
|
||||
``api-timeout`` (compatability)
|
||||
Timeout for the OpenStack API calls client in seconds. Prefer setting
|
||||
this in `clouds.yaml`
|
||||
|
@ -396,7 +396,7 @@ class CleanupWorker(BaseWorker):
|
||||
# so ignore it.
|
||||
return
|
||||
# Remove any local builds that are not in use.
|
||||
if not diskimage or (diskimage and not diskimage.in_use):
|
||||
if not diskimage or (diskimage and not diskimage.image_types):
|
||||
builds_to_keep -= local_builds
|
||||
# TODO(jeblair): When all builds for an image which is not
|
||||
# in use are deleted, the image znode should be deleted as
|
||||
|
@ -49,7 +49,7 @@ class ConfigValidator:
|
||||
|
||||
network = {
|
||||
'name': v.Required(str),
|
||||
'public': bool,
|
||||
'public': bool, # Ignored, but kept for backwards compat
|
||||
}
|
||||
|
||||
providers = {
|
||||
@ -67,7 +67,7 @@ class ConfigValidator:
|
||||
'project-name': str,
|
||||
'max-servers': int,
|
||||
'max-concurrency': int,
|
||||
'pool': str,
|
||||
'pool': str, # Ignored, but kept for backwards compat
|
||||
'image-type': str,
|
||||
'networks': [v.Any(old_network, network)],
|
||||
'ipv6-preferred': bool,
|
||||
@ -108,6 +108,7 @@ class ConfigValidator:
|
||||
'name': str,
|
||||
'pause': bool,
|
||||
'elements': [str],
|
||||
'formats': [str],
|
||||
'release': v.Any(str, int),
|
||||
'rebuild-age': int,
|
||||
'env-vars': dict,
|
||||
|
@ -311,7 +311,7 @@ class NodePoolCmd(NodepoolApp):
|
||||
def config_validate(self):
|
||||
validator = ConfigValidator(self.args.config)
|
||||
validator.validate()
|
||||
log.info("Configuation validation complete")
|
||||
log.info("Configuration validation complete")
|
||||
#TODO(asselin,yolanda): add validation of secure.conf
|
||||
|
||||
def job_list(self):
|
||||
|
@ -195,7 +195,6 @@ def loadConfig(config_path):
|
||||
else:
|
||||
n.name = network.get('name')
|
||||
n.id = None
|
||||
n.public = network.get('public', False)
|
||||
p.ipv6_preferred = provider.get('ipv6-preferred')
|
||||
p.clean_floating_ips = provider.get('clean-floating-ips')
|
||||
p.azs = provider.get('availability-zones')
|
||||
@ -252,15 +251,13 @@ def loadConfig(config_path):
|
||||
#self.log.error("%s: ignoring env-vars; "
|
||||
# "should be a dict" % d.name)
|
||||
d.env_vars = {}
|
||||
d.image_types = set()
|
||||
d.image_types = set(diskimage.get('formats', []))
|
||||
d.pause = bool(diskimage.get('pause', False))
|
||||
d.in_use = False
|
||||
# Do this after providers to build the image-types
|
||||
for provider in newconfig.providers.values():
|
||||
for image in provider.images.values():
|
||||
diskimage = newconfig.diskimages[image.name]
|
||||
diskimage.image_types.add(provider.image_type)
|
||||
diskimage.in_use = True
|
||||
|
||||
for label in config.get('labels', []):
|
||||
l = Label()
|
||||
|
@ -14,6 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
from nodepool import nodedb
|
||||
@ -61,6 +62,20 @@ def dib_image_list(zk):
|
||||
return str(t)
|
||||
|
||||
|
||||
def dib_image_list_json(zk):
|
||||
objs = []
|
||||
for image_name in zk.getImageNames():
|
||||
for build_no in zk.getBuildNumbers(image_name):
|
||||
build = zk.getBuild(image_name, build_no)
|
||||
objs.append({'id' : '-'.join([image_name, build_no]),
|
||||
'image': image_name,
|
||||
'builder': build.builder,
|
||||
'formats': build.formats,
|
||||
'state': build.state,
|
||||
'age': int(build.state_time)
|
||||
})
|
||||
return json.dumps(objs)
|
||||
|
||||
def image_list(zk):
|
||||
t = PrettyTable(["Build ID", "Upload ID", "Provider", "Image",
|
||||
"Provider Image Name", "Provider Image ID", "State",
|
||||
|
@ -70,6 +70,8 @@ targets:
|
||||
|
||||
diskimages:
|
||||
- name: trusty
|
||||
formats:
|
||||
- tar
|
||||
pause: False
|
||||
elements:
|
||||
- ubuntu
|
||||
|
38
nodepool/tests/fixtures/node_diskimage_only.yaml
vendored
Normal file
38
nodepool/tests/fixtures/node_diskimage_only.yaml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
elements-dir: .
|
||||
images-dir: '{images_dir}'
|
||||
|
||||
cron:
|
||||
check: '*/15 * * * *'
|
||||
cleanup: '*/1 * * * *'
|
||||
|
||||
zmq-publishers:
|
||||
- tcp://localhost:8881
|
||||
|
||||
gearman-servers:
|
||||
- host: localhost
|
||||
port: {gearman_port}
|
||||
|
||||
zookeeper-servers:
|
||||
- host: {zookeeper_host}
|
||||
port: {zookeeper_port}
|
||||
chroot: {zookeeper_chroot}
|
||||
|
||||
labels: []
|
||||
|
||||
providers: []
|
||||
|
||||
targets: []
|
||||
|
||||
diskimages:
|
||||
- name: fake-image
|
||||
formats:
|
||||
- tar
|
||||
elements:
|
||||
- fedora
|
||||
- vm
|
||||
release: 21
|
||||
env-vars:
|
||||
TMPDIR: /opt/dib_tmp
|
||||
DIB_IMAGE_CACHE: /opt/dib_cache
|
||||
DIB_CLOUD_IMAGES: http://download.fedoraproject.org/pub/fedora/linux/releases/test/21-Beta/Cloud/Images/x86_64/
|
||||
BASE_IMAGE_FILE: Fedora-Cloud-Base-20141029-21_Beta.x86_64.qcow2
|
@ -278,3 +278,8 @@ class TestNodePoolBuilder(tests.DBTestCase):
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
# Make sure our cleanup worker properly removes the first build.
|
||||
self.waitForBuildDeletion('fake-image', '0000000001')
|
||||
|
||||
def test_diskimage_build_only(self):
|
||||
configfile = self.setup_config('node_diskimage_only.yaml')
|
||||
self._useBuilder(configfile)
|
||||
self.waitForBuild('fake-image', '0000000001')
|
||||
|
@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import urllib2
|
||||
|
||||
@ -39,5 +40,33 @@ class TestWebApp(tests.DBTestCase):
|
||||
req = urllib2.Request(
|
||||
"http://localhost:%s/image-list" % port)
|
||||
f = urllib2.urlopen(req)
|
||||
self.assertEqual(f.info().getheader('Content-Type'),
|
||||
'application/text')
|
||||
data = f.read()
|
||||
self.assertTrue('fake-image' in data)
|
||||
|
||||
@skip("Disabled for early v3 development")
|
||||
def test_dib_image_list_json(self):
|
||||
configfile = self.setup_config('node.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self._useBuilder(configfile)
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
self.waitForNodes(pool)
|
||||
|
||||
req = urllib2.Request(
|
||||
"http://localhost:%s/dib-image-list.json" % port)
|
||||
f = urllib2.urlopen(req)
|
||||
self.assertEqual(f.info().getheader('Content-Type'),
|
||||
'application/json')
|
||||
data = f.read()
|
||||
objs = json.loads(data)
|
||||
# make sure this is valid json and has some of the
|
||||
# non-changing keys
|
||||
self.assertDictContainsSubset({'id': 'fake-image-0000000001',
|
||||
'formats': ['qcow2'],
|
||||
'state': 'ready'}, objs[0])
|
||||
|
@ -75,21 +75,28 @@ class WebApp(threading.Thread):
|
||||
if result:
|
||||
return result
|
||||
if path == '/image-list':
|
||||
table = status.image_list(self.nodepool.getZK())
|
||||
output = status.image_list(self.nodepool.getZK())
|
||||
elif path == '/dib-image-list':
|
||||
table = status.dib_image_list(self.nodepool.getZK())
|
||||
output = status.dib_image_list(self.nodepool.getZK())
|
||||
elif path == '/dib-image-list.json':
|
||||
output = status.dib_image_list_json(self.nodepool.getZK())
|
||||
else:
|
||||
return None
|
||||
return self.cache.put(path, table)
|
||||
return self.cache.put(path, output)
|
||||
|
||||
def app(self, request):
|
||||
result = self.get_cache(request.path)
|
||||
if result is None:
|
||||
raise webob.exc.HTTPNotFound()
|
||||
last_modified, table = result
|
||||
last_modified, output = result
|
||||
|
||||
response = webob.Response(body=table,
|
||||
content_type='text/plain')
|
||||
if request.path.endswith('.json'):
|
||||
content_type = 'application/json'
|
||||
else:
|
||||
content_type = 'application/text'
|
||||
|
||||
response = webob.Response(body=output,
|
||||
content_type=content_type)
|
||||
response.headers['Access-Control-Allow-Origin'] = '*'
|
||||
|
||||
response.cache_control.public = True
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash -x
|
||||
#!/bin/bash -ex
|
||||
|
||||
NODEPOOL_INSTALL=${NODEPOOL_INSTALL:-/opt/stack/new/nodepool-venv}
|
||||
NODEPOOL_CONFIG=${NODEPOOL_CONFIG:-/etc/nodepool/nodepool.yaml}
|
||||
@ -9,7 +9,7 @@ NODEPOOL="$NODEPOOL_INSTALL/bin/nodepool -c $NODEPOOL_CONFIG -s $NODEPOOL_SECURE
|
||||
# NOTE(pabelanger): Be sure to also update devstack/settings if you change the
|
||||
# defaults.
|
||||
NODEPOOL_PAUSE_CENTOS_7_DIB=${NODEPOOL_PAUSE_CENTOS_7_DIB:-true}
|
||||
NODEPOOL_PAUSE_FEDORA_24_DIB=${NODEPOOL_PAUSE_FEDORA_24_DIB:-true}
|
||||
NODEPOOL_PAUSE_FEDORA_25_DIB=${NODEPOOL_PAUSE_FEDORA_25_DIB:-true}
|
||||
NODEPOOL_PAUSE_UBUNTU_PRECISE_DIB=${NODEPOOL_PAUSE_UBUNTU_PRECISE_DIB:-true}
|
||||
NODEPOOL_PAUSE_UBUNTU_TRUSTY_DIB=${NODEPOOL_PAUSE_UBUNTU_TRUSTY_DIB:-false}
|
||||
NODEPOOL_PAUSE_UBUNTU_XENIAL_DIB=${NODEPOOL_PAUSE_UBUNTU_XENIAL_DIB:-true}
|
||||
@ -49,11 +49,11 @@ if [ $NODEPOOL_PAUSE_CENTOS_7_DIB = 'false' ]; then
|
||||
waitfornode centos-7
|
||||
fi
|
||||
|
||||
if [ $NODEPOOL_PAUSE_FEDORA_24_DIB = 'false' ]; then
|
||||
if [ $NODEPOOL_PAUSE_FEDORA_25_DIB = 'false' ]; then
|
||||
# check that image built
|
||||
waitforimage fedora-24
|
||||
waitforimage fedora-25
|
||||
# check image was bootable
|
||||
waitfornode fedora-24
|
||||
waitfornode fedora-25
|
||||
fi
|
||||
|
||||
if [ $NODEPOOL_PAUSE_UBUNTU_PRECISE_DIB = 'false' ]; then
|
||||
@ -70,7 +70,7 @@ if [ $NODEPOOL_PAUSE_UBUNTU_TRUSTY_DIB = 'false' ]; then
|
||||
waitfornode ubuntu-trusty
|
||||
fi
|
||||
|
||||
if [ $NODEPOOL_PAUSE_UBUNTU_XENIAL = 'false' ]; then
|
||||
if [ $NODEPOOL_PAUSE_UBUNTU_XENIAL_DIB = 'false' ]; then
|
||||
# check that image built
|
||||
waitforimage ubuntu-xenial
|
||||
# check image was bootable
|
||||
|
Loading…
x
Reference in New Issue
Block a user