Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/doc/sphinx/Pacemaker_Development/c.rst b/doc/sphinx/Pacemaker_Development/c.rst
index 7f9bc68155..1b6aed11ec 100644
--- a/doc/sphinx/Pacemaker_Development/c.rst
+++ b/doc/sphinx/Pacemaker_Development/c.rst
@@ -1,287 +1,304 @@
+.. index::
+ single: C
+ pair: C; guidelines
+
C Coding Guidelines
-------------------
+.. index::
+ pair: C; style
+
Style Guidelines
################
Pacemaker is a large, distributed project accepting contributions from
developers with a wide range of skill levels and organizational affiliations,
and maintained by multiple people over long periods of time. The guidelines in
this section are not technically better than alternative approaches, but make
project management easier.
Many of these simply ensure stylistic consistency, which makes reading,
writing, and reviewing code easier.
.. index::
pair: C; boilerplate
- pair: licensing; C boilerplate
+ pair: license; C
+ pair: copyright; C
C Boilerplate
_____________
Every C file should start with a short copyright notice:
.. code-block:: c
/*
* Copyright <YYYY[-YYYY]> the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under <LICENSE> WITHOUT ANY WARRANTY.
*/
*<LICENSE>* should follow the policy set forth in the
`COPYING <https://github.com/ClusterLabs/pacemaker/blob/master/COPYING>`_ file,
generally one of "GNU General Public License version 2 or later (GPLv2+)"
or "GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)".
Header files should additionally protect against multiple inclusion by defining
a unique symbol in the form ``PCMK__<capitalized_header_name>__H``. For example:
.. code-block:: c
#ifndef PCMK__MY_HEADER_H
# define PCMK__MY_HEADER_H
// header code here
#endif // PCMK__MY_HEADER_H
Public API header files should additionally declare "C" compatibility for
inclusion by C++, and give a Doxygen file description. For example:
.. code-block:: c
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file
* \brief My brief description here
* \ingroup core
*/
// header code here
#ifdef __cplusplus
}
#endif
-Line Formatting
-_______________
-
.. index::
pair: C; whitespace
+Line Formatting
+_______________
+
* Indentation must be 4 spaces, no tabs.
* Do not leave trailing whitespace.
* Lines should be no longer than 80 characters unless limiting line length
significantly impacts readability.
+.. index::
+ pair: C; pointer
+
Pointers
________
-.. index::
- pair: C; pointers
-
* The ``*`` goes by the variable name, not the type:
.. code-block:: c
char *foo;
* Use a space before the ``*`` and after the closing parenthesis in a cast:
.. code-block:: c
char *foo = (char *) bar;
+.. index::
+ pair: C; function
+
Function Definitions
____________________
-.. index::
- pair: C; functions
-
* In the function definition, put the return type on its own line, and place
the opening brace by itself on a line.
* For functions with enough arguments that they must break to the next line,
align arguments with the first argument.
* When a function argument is a function itself, use the pointer form.
.. code-block:: c
static int
function_name(int bar, const char *a, const char *b,
const char *c, void (*d)())
{
* If a function name gets really long, start the arguments on their own line
with 8 spaces of indentation:
.. code-block:: c
static int
really_really_long_function_name_this_is_getting_silly_now(
int bar, const char *a, const char *b,
const char *c, const char *d)
{
Control Statements (if, else, while, for, switch)
_________________________________________________
* The keyword is followed by one space, then left parenthesis without space,
condition, right parenthesis, space, opening bracket on the same line.
``else`` and ``else if`` are on the same line with the ending brace and
opening brace, separated by a space.
* Always use braces around control statement blocks, even if they only contain
one line. This makes code review diffs smaller if a line gets added in the
future, and avoids any chance of bad indenting making a line incorrectly
appear to be part of the block.
* Do not put assignments in ``if`` or ``while`` conditionals. This ensures that
the developer's intent is always clear, making code reviews easier and
reducing the chance of using assignment where comparison is intended.
.. code-block:: c
a = f();
if (a < 0) {
statement1;
} else if (some_other_condition) {
statement2;
} else {
statement3;
}
* In a ``switch`` statement, ``case`` is indented one level, and the body of
each ``case`` is indented by another level. The opening brace is on the same
line as ``switch``.
.. code-block:: c
switch (expression) {
case 0:
command1;
break;
case 1:
command2;
break;
default:
command3;
}
+.. index::
+ pair: C; operator
+
Operators
_________
-.. index::
- pair: C; operators
-
* Operators have spaces from both sides.
* Do not rely on operator precedence; use parentheses when mixing operators
with different priority.
* No space is used after opening parenthesis and before closing parenthesis.
.. code-block:: c
x = a + b - (c * d);
Best Practices
##############
The guidelines in this section offer technical advantages.
.. index::
pair: C; struct
pair: C; enum
New Struct and Enum Members
___________________________
In the public APIs, always add new ``struct`` members to the end of the
``struct``. This allows us to maintain backward API/ABI compatibility (as long
as the application being linked allocates structs via API functions).
This generally applies to ``enum`` values as well, as the compiler will define
``enum`` values to 0, 1, etc., in the order given, so inserting a value in the
middle will change the numerical values of all later values, making them
backward-incompatible. However, if enum numerical values are explicitly
specified rather than left to the compiler, new values can be added anywhere.
.. index::
pair: C; API documentation
-Documentation
-_____________
+API documentation
+_________________
All public API header files, functions, structs, enums, etc.,
should be documented with Doxygen comment blocks, as Pacemaker's
`online API documentation <https://clusterlabs.org/pacemaker/doxygen/>`_
is automatically generated via Doxygen. It is helpful to document
private symbols in the same way, with an ``\internal`` tag in the
Doxygen comment.
-Symbol Naming
-_____________
-
.. index::
pair: C; naming
+Symbol Naming
+_____________
+
* All file and function names should be unique across the entire project,
to allow for individual tracing via ``PCMK_trace_files`` and
``PCMK_trace_functions``, as well as making detail logs easier to follow.
* Any exposed symbols in libraries (non-``static`` function names, type names,
etc.) must begin with a prefix appropriate to the library, for example,
``pcmk_``, ``pe_``, ``st_``, ``lrm_``. This reduces the chance of naming
collisions with software linked against the library.
* Time intervals are sometimes represented in Pacemaker code as user-defined
text specifications (e.g. "10s"), other times as an integer number of
seconds or milliseconds, and still other times as a string representation
of an integer number. Variables for these should be named with an indication
of which is being used (e.g. ``interval_spec``, ``interval_ms``, or
``interval_ms_s`` instead of ``interval``).
+.. index::
+ pair: C; memory
+
Memory Allocation
_________________
* Always use ``calloc()`` rather than ``malloc()``. It has no additional cost on
modern operating systems, and reduces the severity and security risks of
uninitialized memory usage bugs.
+.. index::
+ pair: C; logging
+
Logging
_______
* When format strings are used for derived data types whose implementation may
vary across platforms (``pid_t``, ``time_t``, etc.), the safest approach is
to use ``%lld`` in the format string, and cast the value to ``long long``.
* Do *not* pass ``NULL`` as an argument to satisfy the ``%s`` format specifier
in logging (and more generally, ``printf``-style) functions. When the string
"<null>" is a sufficient output representation in such case, you can use the
``crm_str()`` convenience macro; otherwise, the ternary operator is an
obvious choice.
+.. index::
+ pair: C; regular expression
+
Regular Expressions
___________________
- Use ``REG_NOSUB`` with ``regcomp()`` whenever possible, for efficiency.
- Be sure to use ``regfree()`` appropriately.
vim Settings
____________
.. index:: vim
Developers who use ``vim`` to edit source code can add the following settings
to their ``~/.vimrc`` file to follow Pacemaker C coding guidelines:
.. code-block:: none
" follow Pacemaker coding guidelines when editing C source code files
filetype plugin indent on
au FileType c setlocal expandtab tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80
autocmd BufNewFile,BufRead *.h set filetype=c
let c_space_errors = 1
diff --git a/doc/sphinx/Pacemaker_Development/faq.rst b/doc/sphinx/Pacemaker_Development/faq.rst
index 75aac0cc8e..8e029f5c18 100644
--- a/doc/sphinx/Pacemaker_Development/faq.rst
+++ b/doc/sphinx/Pacemaker_Development/faq.rst
@@ -1,143 +1,148 @@
Frequently Asked Questions
--------------------------
:Q: Who is this document intended for?
:A: Anyone who wishes to read and/or edit the Pacemaker source code.
Casual contributors should feel free to read just this FAQ, and
consult other chapters as needed.
----
-.. index:: downloads, source code, git, GitHub
+.. index::
+ single: download
+ single: source code
+ single: git
+ single: git; GitHub
:Q: Where is the source code for Pacemaker?
:A: The `source code for Pacemaker <https://github.com/ClusterLabs/pacemaker>`_ is
kept on `GitHub <https://github.com/>`_, as are all software projects under the
`ClusterLabs <https://github.com/ClusterLabs>`_ umbrella. Pacemaker uses
`Git <https://git-scm.com/>`_ for source code management. If you are a Git newbie,
the `gittutorial(7) man page <http://schacon.github.io/git/gittutorial.html>`_
is an excellent starting point. If you're familiar with using Git from the
command line, you can create a local copy of the Pacemaker source code with:
**git clone https://github.com/ClusterLabs/pacemaker.git**
----
-.. index:: branches
+.. index::
+ single: git; branch
:Q: What are the different Git branches and repositories used for?
:A: * The `master branch <https://github.com/ClusterLabs/pacemaker/tree/master>`_
is the primary branch used for development.
* The `2.0 branch <https://github.com/ClusterLabs/pacemaker/tree/2.0>`_ contains
the latest official release, and normally does not receive any changes.
During the release cycle, it will contain release candidates for the
next official release, and will receive only bug fixes.
* The `1.1 branch <https://github.com/ClusterLabs/pacemaker/tree/1.1>`_ is similar
to both the master and 2.0 branches, but for the 1.1 release series.
The 1.1 branch receives only backports of certain bug fixes and
backward-compatible features from the master branch. During the release
cycle, it will contain release candidates for the next official 1.1 release.
* The `1.0 repository <https://github.com/ClusterLabs/pacemaker-1.0>`_ is a
frozen snapshot of the 1.0 release series, and is no longer developed.
* Messages will be posted to the
`developers@ClusterLabs.org <https://lists.ClusterLabs.org/mailman/listinfo/developers>`_
mailing list during the release cycle, with instructions about which
branches to use when submitting requests.
----
:Q: How do I build from the source code?
:A: See `INSTALL.md <https://github.com/ClusterLabs/pacemaker/blob/master/INSTALL.md>`_
in the main checkout directory.
----
:Q: What coding style should I follow?
:A: You'll be mostly fine if you simply follow the example of existing code.
When unsure, see the relevant chapter of this document for language-specific
recommendations. Pacemaker has grown and evolved organically over many years,
so you will see much code that doesn't conform to the current guidelines. We
discourage making changes solely to bring code into conformance, as any change
requires developer time for review and opens the possibility of adding bugs.
However, new code should follow the guidelines, and it is fine to bring lines
of older code into conformance when modifying that code for other reasons.
----
.. index::
- pair: git; commit messages
+ single: git; commit message
:Q: How should I format my Git commit messages?
:A: See existing examples in the git log. The first line should look like
+change-type: affected-code: explanation+ where +change-type+ should be
+Fix+ or +Bug+ for most bug fixes, +Feature+ for new features, +Log+ for
changes to log messages or handling, +Doc+ for changes to documentation or
comments, or +Test+ for changes in CTS and regression tests. You will
sometimes see +Low+, +Med+ (or +Mid+) and +High+ used instead for bug fixes,
to indicate the severity. The important thing is that only commits with
+Feature+, +Fix+, +Bug+, or +High+ will automatically be included in the
change log for the next release. The +affected-code+ is the name of the
component(s) being changed, for example, +controller+ or
+libcrmcommon+ (it's more free-form, so don't sweat getting it exact). The
+explanation+ briefly describes the change. The git project recommends the
entire summary line stay under 50 characters, but more is fine if needed for
clarity. Except for the most simple and obvious of changes, the summary should
be followed by a blank line and then a longer explanation of 'why' the change
was made.
----
:Q: How can I test my changes?
:A: Most importantly, Pacemaker has regression tests for most major components;
these will automatically be run for any pull requests submitted through
GitHub. Additionally, Pacemaker's Cluster Test Suite (CTS) can be used to set
up a test cluster and run a wide variety of complex tests. This document will
have more detail on testing in the future.
----
-.. index:: licensing
+.. index:: license
:Q: What is Pacemaker's license?
:A: Except where noted otherwise in the file itself, the source code for all
Pacemaker programs is licensed under version 2 or later of the GNU General
Public License (`GPLv2+ <https://www.gnu.org/licenses/gpl-2.0.html>`_), its
headers and libraries under version 2.1 or later of the less restrictive
GNU Lesser General Public License
(`LGPLv2.1+ <https://www.gnu.org/licenses/lgpl-2.1.html>`_),
its documentation under version 4.0 or later of the
Creative Commons Attribution-ShareAlike International Public License
(`CC-BY-SA-4.0 <https://creativecommons.org/licenses/by-sa/4.0/legalcode>`_),
and its init scripts under the
`Revised BSD <https://opensource.org/licenses/BSD-3-Clause>`_ license. If you find
any deviations from this policy, or wish to inquire about alternate licensing
arrangements, please e-mail the
`developers@ClusterLabs.org <https://lists.ClusterLabs.org/mailman/listinfo/developers>`_
mailing list. Licensing issues are also discussed on the
`ClusterLabs wiki <https://wiki.ClusterLabs.org/wiki/License>`_.
----
:Q: How can I contribute my changes to the project?
:A: Contributions of bug fixes or new features are very much appreciated!
Patches can be submitted as
`pull requests <https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests>`_
via GitHub (the preferred method, due to its excellent
`features <https://github.com/features/>`_), or e-mailed to the
`developers@ClusterLabs.org <https://lists.ClusterLabs.org/mailman/listinfo/developers>`_
mailing list as an attachment in a format Git can import. Authors may only
submit changes that they have the right to submit under the open source
license indicated in the affected files.
----
-.. index:: mailing lists
+.. index:: mailing list
:Q: What if I still have questions?
:A: Ask on the
`developers@ClusterLabs.org <https://lists.ClusterLabs.org/mailman/listinfo/developers>`_
mailing list for development-related questions, or on the
`users@ClusterLabs.org <https://lists.ClusterLabs.org/mailman/listinfo/users>`_
mailing list for general questions about using Pacemaker.
Developers often also hang out on `freenode's <http://freenode.net/>`_
#clusterlabs IRC channel.
diff --git a/doc/sphinx/Pacemaker_Development/general.rst b/doc/sphinx/Pacemaker_Development/general.rst
index a1fd103fc9..9d9dcec1cf 100644
--- a/doc/sphinx/Pacemaker_Development/general.rst
+++ b/doc/sphinx/Pacemaker_Development/general.rst
@@ -1,37 +1,40 @@
+.. index::
+ single: guidelines; all languages
+
General Guidelines for All Languages
------------------------------------
+.. index:: copyright
+
Copyright
#########
-.. index:: copyright
-
When copyright notices are added to a file, they should look like this:
.. note:: **Copyright Notice Format**
| Copyright *YYYY[-YYYY]* the Pacemaker project contributors
|
| The version control history for this file may have further details.
The first *YYYY* is the year the file was *originally* published. The original
date is important for two reasons: when two entities claim copyright ownership
of the same work, the earlier claim generally prevails; and copyright
expiration is generally calculated from the original publication date. [1]_
If the file is modified in later years, add *-YYYY* with the most recent year
of modification. Even though Pacemaker is an ongoing project, copyright notices
are about the years of *publication* of specific content.
Copyright notices are intended to indicate, but do not affect, copyright
*ownership*, which is determined by applicable laws and regulations. Authors
may put more specific copyright notices in their commit messages if desired.
.. rubric:: Footnotes
.. [1] See the U.S. Copyright Office's `"Compendium of U.S. Copyright Office
Practices" <https://www.copyright.gov/comp3/>`_, particularly "Chapter
2200: Notice of Copyright", sections 2205.1(A) and 2205.1(F), or
`"Updating Copyright Notices"
<https://techwhirl.com/updating-copyright-notices/>`_ for a more
readable summary.
diff --git a/doc/sphinx/Pacemaker_Development/python.rst b/doc/sphinx/Pacemaker_Development/python.rst
index 5b2495e2b1..8c28d44f8e 100644
--- a/doc/sphinx/Pacemaker_Development/python.rst
+++ b/doc/sphinx/Pacemaker_Development/python.rst
@@ -1,147 +1,153 @@
+.. index::
+ single: Python
+ pair: Python; guidelines
+
Python Coding Guidelines
------------------------
+.. index::
+ pair: Python; boilerplate
+ pair: license; Python
+ pair: copyright; Python
+
.. _s-python-boilerplate:
Python Boilerplate
##################
-.. index::
- pair: Python; boilerplate
- pair: licensing; Python boilerplate
-
If a Python file is meant to be executed (as opposed to imported), it should
have a ``.in`` extension, and its first line should be:
.. code-block:: python
#!@PYTHON@
which will be replaced with the appropriate python executable when Pacemaker is
built. To make that happen, add an ``AC_CONFIG_FILES()`` line to
``configure.ac``, and add the file name without ``.in`` to ``.gitignore`` (see
existing examples).
After the above line if any, every Python file should start like this:
.. code-block:: python
""" <BRIEF-DESCRIPTION>
"""
# Pacemaker targets compatibility with Python 2.7 and 3.2+
from __future__ import print_function, unicode_literals, absolute_import, division
__copyright__ = "Copyright <YYYY[-YYYY]> the Pacemaker project contributors"
__license__ = "<LICENSE> WITHOUT ANY WARRANTY"
*<BRIEF-DESCRIPTION>* is obviously a brief description of the file's
purpose. The string may contain any other information typically used in
a Python file `docstring <https://www.python.org/dev/peps/pep-0257/>`_.
The ``import`` statement is discussed further in :ref:`s-python-future-imports`.
``<LICENSE>`` should follow the policy set forth in the
`COPYING <https://github.com/ClusterLabs/pacemaker/blob/master/COPYING>`_ file,
generally one of "GNU General Public License version 2 or later (GPLv2+)"
or "GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)".
-Python Compatibility
-####################
-
.. index::
single: Python; 2
single: Python; 3
- single: Python; versions
+ single: Python; version
+
+Python Compatibility
+####################
Pacemaker targets compatibility with Python 2.7, and Python 3.2 and
later. These versions have added features to be more compatible with each
other, allowing us to support both the 2 and 3 series with the same code. It is
a good idea to test any changes with both Python 2 and 3.
.. _s-python-future-imports:
Python Future Imports
_____________________
The future imports used in :ref:`s-python-boilerplate` mean:
* All print statements must use parentheses, and printing without a newline
is accomplished with the ``end=' '`` parameter rather than a trailing comma.
* All string literals will be treated as Unicode (the ``u`` prefix is
unnecessary, and must not be used, because it is not available in Python 3.2).
* Local modules must be imported using ``from . import`` (rather than just
``import``). To import one item from a local module, use
``from .modulename import`` (rather than ``from modulename import``).
* Division using ``/`` will always return a floating-point result (use ``//``
if you want the integer floor instead).
Other Python Compatibility Requirements
_______________________________________
* When specifying an exception variable, always use ``as`` instead of a comma
(e.g. ``except Exception as e`` or ``except (TypeError, IOError) as e``).
Use ``e.args`` to access the error arguments (instead of iterating over or
subscripting ``e``).
* Use ``in`` (not ``has_key()``) to determine if a dictionary has a particular
key.
* Always use the I/O functions from the ``io`` module rather than the native
I/O functions (e.g. ``io.open()`` rather than ``open()``).
* When opening a file, always use the ``t`` (text) or ``b`` (binary) mode flag.
* When creating classes, always specify a parent class to ensure that it is a
"new-style" class (e.g. ``class Foo(object):`` rather than ``class Foo:``).
* Be aware of the bytes type added in Python 3. Many places where strings are
used in Python 2 use bytes or bytearrays in Python 3 (for example, the pipes
used with ``subprocess.Popen()``). Code should handle both possibilities.
* Be aware that the ``items()``, ``keys()``, and ``values()`` methods of
dictionaries return lists in Python 2 and views in Python 3. In many case, no
special handling is required, but if the code needs to use list methods on
the result, cast the result to list first.
* Do not raise or catch strings as exceptions (e.g. ``raise "Bad thing"``).
* Do not use the ``cmp`` parameter of sorting functions (use ``key`` instead,
if needed) or the ``__cmp__()`` method of classes (implement rich comparison
methods such as ``__lt__()`` instead, if needed).
* Do not use the ``buffer`` type.
* Do not use features not available in all targeted Python versions. Common
examples include:
* The ``html``, ``ipaddress``, and ``UserDict`` modules
* The ``subprocess.run()`` function
* The ``subprocess.DEVNULL`` constant
* ``subprocess`` module-specific exceptions
Python Usages to Avoid
______________________
Avoid the following if possible, otherwise research the compatibility issues
involved (hacky workarounds are often available):
* long integers
* octal integer literals
* mixed binary and string data in one data file or variable
* metaclasses
* ``locale.strcoll`` and ``locale.strxfrm``
* the ``configparser`` and ``ConfigParser`` modules
* importing compatibility modules such as ``six`` (so we don't have
to add them to Pacemaker's dependencies)
+.. index::
+ pair: Python; whitespace
+
Formatting Python Code
######################
-.. index:: Python; formatting
-
* Indentation must be 4 spaces, no tabs.
* Do not leave trailing whitespace.
* Lines should be no longer than 80 characters unless limiting line length
significantly impacts readability. For Python, this limitation is
flexible since breaking a line often impacts readability, but
definitely keep it under 120 characters.
* Where not conflicting with this style guide, it is recommended (but not
required) to follow `PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_.
* It is recommended (but not required) to format Python code such that
``pylint
--disable=line-too-long,too-many-lines,too-many-instance-attributes,too-many-arguments,too-many-statements``
produces minimal complaints (even better if you don't need to disable all
those checks).

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 6:53 AM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018330
Default Alt Text
(25 KB)

Event Timeline