[docs] Fix readme for docker image

* fix indents and code quotas
* fix version of latest release + add unittest for checking this

Change-Id: Iab8f7fec3117cdcb84708f3a291a6926b3eb085f
This commit is contained in:
Andrey Kurilin 2019-02-05 17:38:43 +02:00
parent 5e2721c8ee
commit 4e5890af43
5 changed files with 151 additions and 50 deletions

View File

@ -12,21 +12,24 @@ pre-installed plugins for Kubernetes, OpenStack, etc).
You can use this image as a base image and extend it with installation of
additional plugins:
>\# It is an example of Dockerfile for xrally/xrally_docker image. There are
>\# only 2 critical lines: `FROM instruction` and the last line is a check
>\# for rally user is used.
>
>\# Tags of the image are the same as releases of xRally/Rally
>FROM xrally/xrally:1.3.0
>
>\# "rally" user (which is selected by-default) is owner of "/rally" directory,
>\# so there is no need to call chown or switch the user
>COPY . /rally/xrally_docker
>WORKDIR /rally/xrally_docker
>\# to install package system-wide, we need to temporary switch to root user
>USER root
>RUN pip install .
>USER rally
# It is an example of Dockerfile for xrally/xrally_docker image. There are
# only 2 critical lines: `FROM instruction` and the last line is a check
# for rally user is used.
#
# Tags of the image are the same as releases of xRally/Rally
FROM xrally/xrally:1.4.0
# "rally" user (which is selected by-default) is owner of "/rally" directory,
# so there is no need to call chown or switch the user
COPY . /rally/xrally_docker
WORKDIR /rally/xrally_docker
# to install package system-wide, we need to temporary switch to root user
USER root
RUN pip install .
# switch back to rally user for avoid permission conflicts
USER rally
or launch workloads based on in-tree plugins (see the next section for more
details)
@ -36,8 +39,8 @@ details)
First of all, you need to pull the container. We suggest to use the last
tagged version:
*\# pull the 1.3.0 image (the latest release at the point of writing the note)*
> $ docker pull xrally/xrally:1.3.0
# pull the 1.4.0 image (the latest release at the point of writing the note)
$ docker pull xrally/xrally:1.4.0
**WARNING: never attach folders and volumes to `/rally` inside the container. It can break everything.**
@ -52,29 +55,29 @@ docker volumes or mount the directory.
* use docker volumes. It is the easiest way. You just need to do something like:
> $ docker volume create --name rally_volume
> $ docker run -v rally_volume:/home/rally/.rally xrally/xrally:1.1.0 env create --name "foo"
$ docker volume create --name rally_volume
$ docker run -v rally_volume:/home/rally/.rally xrally/xrally:1.4.0 env create --name "foo"
* mount outer directory inside the container
*\# you can create directory in whatever you want to place, but you*
*\# may wish to make the data available for all users*
> $ sudo mkdir /var/lib/rally_container
# you can create directory in whatever you want to place, but you
# may wish to make the data available for all users
$ sudo mkdir /var/lib/rally_container
# In order for the directory to be accessible by the Rally user
# (uid: 65500) inside the container, it must be accessible by UID
# 65500 *outside* the container as well, which is why it is created
# in ``/var/lib/rally_container``. Creating it in your home directory is
# only likely to work if your home directory has excessively open
# permissions (e.g., ``0755``), which is not recommended.
$ sudo chown 65500 /var/lib/rally_container
*\# In order for the directory to be accessible by the Rally user*
*\# (uid: 65500) inside the container, it must be accessible by UID*
*\# 65500 *outside* the container as well, which is why it is created*
*\# in ``/var/lib/rally_container``. Creating it in your home directory is*
*\# only likely to work if your home directory has excessively open*
*\# permissions (e.g., ``0755``), which is not recommended.*
> $ sudo chown 65500 /var/lib/rally_container
# As opposed to mounting docker image, you must initialize rally database*
$ docker run -v /var/lib/rally_container:/home/rally/.rally xrally/xrally db create
*\# As opposed to mounting docker image, you must initialize rally database*
> $ docker run -v /var/lib/rally_container:/home/rally/.rally xrally/xrally db create
*\# And finally, you can start doing your things.*
> $ docker run -v /var/lib/rally_container:/home/rally/.rally xrally/xrally env create --name "foo"
# And finally, you can start doing your things.*
$ docker run -v /var/lib/rally_container:/home/rally/.rally xrally/xrally env create --name "foo"
Have fun!

View File

@ -1,8 +1,8 @@
ReadMe of <rally-repo>/etc/docker dir
=====================================
We are using automated docker image builds on [Docker Hub](
https://hub.docker.com/) which allows to reduce time of making new releases.
We are using automated docker image builds on `Docker Hub
<https://hub.docker.com/>`_ which allows to reduce time of making new releases.
Docker Hub has one specific feature - each time it builds new image, it
updates the description of the image. The description it takes from README file

View File

@ -0,0 +1,79 @@
# Copyright 2014: Mirantis 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.
from docutils import nodes
import os
import re
import rally
from tests.unit.doc import utils
from tests.unit import test
ROOT_DIR = os.path.dirname(os.path.dirname(rally.__file__))
DOCKER_DIR = os.path.join(ROOT_DIR, "etc", "docker")
class DockerReadmeTestCase(test.TestCase):
RE_RELEASE = re.compile(r"\[(?P<version>[0-9]+\.[0-9]+.[0.9]+)\]")
def get_rally_releases(self):
full_path = os.path.join(ROOT_DIR, "CHANGELOG.rst")
with open(full_path) as f:
changelog = f.read()
changelog = utils.parse_rst(changelog)
if len(changelog) != 1:
self.fail("'%s' file should contain one global section "
"with subsections for each release." % full_path)
releases = []
for node in changelog[0].children:
if not isinstance(node, nodes.section):
continue
title = node.astext().split("\n", 1)[0]
result = self.RE_RELEASE.match(title)
if result:
releases.append(result.groupdict()["version"])
if not releases:
self.fail("'%s' doesn't mention any releases..." % full_path)
return releases
def test_mentioned_latest_version(self):
full_path = os.path.join(ROOT_DIR, "etc/docker/README.md")
with open(full_path) as f:
readme = f.read()
rally_releases = self.get_rally_releases()
latest_release = rally_releases[0]
previous_release = rally_releases[1]
print(rally_releases)
found = False
for i, line in enumerate(readme.split("\n"), 1):
if latest_release in line:
found = True
elif previous_release in line:
self.fail(
"You need to change all places where the latest release is"
" mentioned from %s to %s."
"\n Filename: %s"
"\n Line Number: %s"
"\n Line: %s" %
(previous_release, latest_release, full_path, i, line))
if not found:
self.fail("No latest nor previous release is found at README file "
"for our Docker image. It looks like the format of it "
"had changed. Please adopt the current test suite.")

View File

@ -13,27 +13,16 @@
# License for the specific language governing permissions and limitations
# under the License.
from docutils import frontend
from docutils import nodes
from docutils.parsers import rst
from docutils import utils
from rally.common.plugin import plugin
from rally.common import validation
from rally import plugins
from rally.task import scenario
from tests.unit.doc import utils
from tests.unit import test
def _parse_rst(text):
parser = rst.Parser()
settings = frontend.OptionParser(
components=(rst.Parser,)).get_default_values()
document = utils.new_document(text, settings)
parser.parse(text, document)
return document.children
class DocstringsTestCase(test.TestCase):
def setUp(self):
@ -101,7 +90,7 @@ class DocstringsTestCase(test.TestCase):
# "definitions" means that there is an issue with intends or
# missed empty line before the list title and list items.
if doc_info["description"]:
parsed_docstring = _parse_rst(doc_info["description"])
parsed_docstring = utils.parse_rst(doc_info["description"])
self._iterate_parsed_rst(plg_cls.get_name(),
parsed_docstring,
msg_buffer)
@ -140,7 +129,7 @@ class DocstringsTestCase(test.TestCase):
docstring = base.__doc__
print(name)
parsed_docstring = _parse_rst(docstring)
parsed_docstring = utils.parse_rst(docstring)
self._iterate_parsed_rst(name,
parsed_docstring,
msg_buffer)

30
tests/unit/doc/utils.py Normal file
View File

@ -0,0 +1,30 @@
# 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.
from docutils import frontend
from docutils.parsers import rst
from docutils import utils
import sys
import mock
@mock.patch.object(sys, "stderr")
def parse_rst(text, mock_stderr):
parser = rst.Parser()
settings = frontend.OptionParser(
components=(rst.Parser,)).get_default_values()
document = utils.new_document(text, settings)
parser.parse(text, document)
return document.children