abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+# Helper values for calling builtin functions
+empty :=
+space := $(empty) $(empty)
+comma := ,
+
# Use bash in order to be able to use pipefail
SHELL=/bin/bash
CHECK_MAN = $(top_srcdir)/autotools/check-man
CHECK_VERSION = $(top_srcdir)/autotools/check-version
CHECK_NEWS = $(top_srcdir)/autotools/check-news
+CHECK_IMPORTS = $(top_srcdir)/autotools/check-imports
DOCPP = $(top_srcdir)/autotools/docpp
REPLACE_VARS_SED = autotools/replace_vars.sed
+CONVERT_CONSTANTS = $(top_srcdir)/autotools/convert-constants
# Note: these are automake-specific variables, and must be named after
# the directory + 'dir' suffix
HTOOLS_DIRS = \
htools \
htools/Ganeti \
- htools/Ganeti/HTools
+ htools/Ganeti/HTools \
+ htools/Ganeti/HTools/Program
DIRS = \
autotools \
$(APIDOC_PY_DIR) \
$(APIDOC_HS_DIR) \
$(APIDOC_HS_DIR)/Ganeti $(APIDOC_HS_DIR)/Ganeti/HTools \
+ $(APIDOC_HS_DIR)/Ganeti/HTools/Program \
$(COVERAGE_DIR) \
$(COVERAGE_PY_DIR) \
$(COVERAGE_HS_DIR) \
BUILT_SOURCES = \
ganeti \
stamp-srclinks \
- lib/_autoconf.py \
$(all_dirfiles) \
- $(PYTHON_BOOTSTRAP)
+ $(PYTHON_BOOTSTRAP) \
+ $(BUILT_PYTHON_SOURCES)
+
+BUILT_PYTHON_SOURCES = \
+ lib/_autoconf.py \
+ lib/_vcsversion.py
nodist_pkgpython_PYTHON = \
- lib/_autoconf.py
+ $(BUILT_PYTHON_SOURCES)
noinst_PYTHON = \
lib/build/__init__.py \
lib/impexpd/__init__.py
watcher_PYTHON = \
- lib/watcher/__init__.py
+ lib/watcher/__init__.py \
+ lib/watcher/nodemaint.py \
+ lib/watcher/state.py
server_PYTHON = \
lib/server/__init__.py \
doc/design-2.3.rst \
doc/design-htools-2.3.rst \
doc/design-2.4.rst \
+ doc/design-2.5.rst \
doc/design-draft.rst \
doc/design-oob.rst \
+ doc/design-cpu-pinning.rst \
doc/design-query2.rst \
doc/design-x509-ca.rst \
doc/design-http-server.rst \
doc/design-impexp2.rst \
doc/design-lu-generated-jobs.rst \
+ doc/design-multi-reloc.rst \
+ doc/design-network.rst \
+ doc/design-chained-jobs.rst \
+ doc/design-ovf-support.rst \
doc/cluster-merge.rst \
doc/design-shared-storage.rst \
doc/devnotes.rst \
doc/upgrade.rst \
doc/walkthrough.rst
-HS_PROGS = \
- htools/hbal \
- htools/hscan \
- htools/hail \
- htools/hspace
+HS_PROGS = htools/htools
+HS_BIN_ROLES = hbal hscan hspace
HS_ALL_PROGS = $(HS_PROGS) htools/test
HS_PROG_SRCS = $(patsubst %,%.hs,$(HS_ALL_PROGS))
# extra flags that can be overriden on the command line
HEXTRA =
# exclude options for coverage reports
-HPCEXCL = --exclude Main --exclude Ganeti.HTools.QC
+HPCEXCL = --exclude Main --exclude Ganeti.HTools.QC \
+ --exclude Ganeti.Constants \
+ --exclude Ganeti.HTools.Version
HS_LIB_SRCS = \
htools/Ganeti/HTools/CLI.hs \
htools/Ganeti/HTools/Cluster.hs \
+ htools/Ganeti/HTools/Compat.hs \
htools/Ganeti/HTools/Container.hs \
htools/Ganeti/HTools/ExtLoader.hs \
htools/Ganeti/HTools/Group.hs \
htools/Ganeti/HTools/Text.hs \
htools/Ganeti/HTools/Types.hs \
htools/Ganeti/HTools/Utils.hs \
+ htools/Ganeti/HTools/Program/Hail.hs \
+ htools/Ganeti/HTools/Program/Hbal.hs \
+ htools/Ganeti/HTools/Program/Hscan.hs \
+ htools/Ganeti/HTools/Program/Hspace.hs \
htools/Ganeti/Jobs.hs \
htools/Ganeti/Luxi.hs \
htools/Ganeti/OpCodes.hs
-HS_BUILT_SRCS = htools/Ganeti/HTools/Version.hs
+HS_BUILT_SRCS = htools/Ganeti/HTools/Version.hs htools/Ganeti/Constants.hs
HS_BUILT_SRCS_IN = $(patsubst %,%.in,$(HS_BUILT_SRCS))
$(RUN_IN_TEMPDIR): | $(all_dirfiles)
# it changes
doc/html/index.html: $(docrst) $(docpng) doc/conf.py configure.ac \
$(RUN_IN_TEMPDIR) lib/build/sphinx_ext.py lib/opcodes.py lib/ht.py \
- | lib/_autoconf.py
+ | $(BUILT_PYTHON_SOURCES)
@test -n "$(SPHINX)" || \
{ echo 'sphinx-build' not found during configure; exit 1; }
@mkdir_p@ $(dir $@)
qa/qa_utils.py
bin_SCRIPTS =
-iallocators_SCRIPTS =
if WANT_HTOOLS
bin_SCRIPTS += $(filter-out htools/hail,$(HS_PROGS))
-iallocators_SCRIPTS += $(filter htools/hail,$(HS_PROGS))
+install-exec-hook:
+ @mkdir_p@ $(DESTDIR)$(iallocatorsdir)
+# FIXME: this is a hardcoded logic, instead of auto-resolving
+ $(LN_S) -f ../../../bin/htools \
+ $(DESTDIR)$(iallocatorsdir)/hail
+ for role in $(HS_BIN_ROLES); do \
+ $(LN_S) -f htools \
+ $(DESTDIR)$(bindir)/$$role ; \
+ done
endif
$(HS_ALL_PROGS): %: %.hs $(HS_LIB_SRCS) $(HS_BUILT_SRCS) Makefile
- BINARY=$(@:htools/%=%); \
- $(GHC) --make \
- $(HFLAGS) $(HEXTRA) $(HTOOLS_NOCURL) \
- -osuf $$BINARY.o -hisuf $$BINARY.hi \
- $@
+ @if [ -z "$(HTOOLS)" ]; then \
+ echo "Error: htools compilation disabled at configure time" 1>&2 ;\
+ exit 1; \
+ fi
+ @BINARY=$(@:htools/%=%); \
+ if [ "$BINARY" = "test" ] && [ -z "$(GHC_PKG_QUICKCHECK)" ]; then \
+ echo "Error: cannot run unittests without the QuickCheck library (see devnotes.rst)" 1>&2; \
+ exit 1; \
+ fi
+ BINARY=$(@:htools/%=%); $(GHC) --make \
+ $(HFLAGS) $(HEXTRA) \
+ $(HTOOLS_NOCURL) $(HTOOLS_PARALLEL3) \
+ -osuf $$BINARY.o -hisuf $$BINARY.hi $@
# for the htools/test binary, we need to enable profiling/coverage
htools/test: HEXTRA=-fhpc -Wwarn -fno-warn-missing-signatures \
$(PYTHON_BOOTSTRAP_SBIN) \
daemons/ganeti-cleaner
-dist_tools_SCRIPTS = \
+dist_tools_PYTHON = \
tools/burnin \
tools/cfgshell \
tools/cfgupgrade \
tools/setup-ssh \
tools/sanitize-config
+dist_tools_SCRIPTS = \
+ $(dist_tools_PYTHON) \
+ tools/kvm-console-wrapper \
+ tools/xm-console-wrapper
+
pkglib_python_scripts = \
daemons/import-export \
tools/check-cert-expired
pylintrc \
autotools/build-bash-completion \
autotools/check-python-code \
+ autotools/check-imports \
autotools/check-man \
autotools/check-news \
autotools/check-tar \
autotools/check-version \
+ autotools/convert-constants \
autotools/docpp \
autotools/gen-coverage \
autotools/testrunner \
man/hail.1 \
man/hbal.1 \
man/hscan.1 \
- man/hspace.1
+ man/hspace.1 \
+ man/htools.1
manrst = $(patsubst %.1,%.rst,$(patsubst %.7,%.rst,$(patsubst %.8,%.rst,$(man_MANS))))
manhtml = $(patsubst %.rst,%.html,$(manrst))
test/data/bdev-drbd-net-ip4.txt \
test/data/bdev-drbd-net-ip6.txt \
test/data/cert1.pem \
+ test/data/ip-addr-show-dummy0.txt \
+ test/data/ip-addr-show-lo-ipv4.txt \
+ test/data/ip-addr-show-lo-ipv6.txt \
+ test/data/ip-addr-show-lo-oneline-ipv4.txt \
+ test/data/ip-addr-show-lo-oneline-ipv6.txt \
+ test/data/ip-addr-show-lo-oneline.txt \
+ test/data/ip-addr-show-lo.txt \
test/data/proc_drbd8.txt \
test/data/proc_drbd80-emptyline.txt \
test/data/proc_drbd83.txt \
$(python_tests)
nodist_TESTS =
-if WANT_HTOOLS
+if WANT_HTOOLSTESTS
nodist_TESTS += $(haskell_tests)
endif
all_python_code = \
$(dist_sbin_SCRIPTS) \
- $(dist_tools_SCRIPTS) \
+ $(dist_tools_PYTHON) \
$(pkglib_python_scripts) \
$(nodist_pkglib_python_scripts) \
$(python_tests) \
check_python_code = \
$(BUILD_BASH_COMPLETION) \
+ $(CHECK_IMPORTS) \
$(DOCPP) \
$(all_python_code)
ganeti \
ganeti/http/server.py \
$(dist_sbin_SCRIPTS) \
- $(dist_tools_SCRIPTS) \
+ $(dist_tools_PYTHON) \
$(pkglib_python_scripts) \
$(BUILD_BASH_COMPLETION) \
+ $(CHECK_IMPORTS) \
$(DOCPP) \
$(PYTHON_BOOTSTRAP)
+standalone_python_modules = \
+ lib/rapi/client.py \
+ tools/ganeti-listrunner
+
test/daemon-util_unittest.bash: daemons/daemon-util
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner
VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
sed -e "s/%ver%/$$VCSVER/" < $< > $@
-lib/_autoconf.py: Makefile vcs-version | lib/.dir
+htools/Ganeti/Constants.hs: htools/Ganeti/Constants.hs.in \
+ lib/constants.py lib/_autoconf.py $(CONVERT_CONSTANTS)
+ set -e; \
+ { cat $< ; PYTHONPATH=. $(CONVERT_CONSTANTS); } > $@
+
+lib/_autoconf.py: Makefile | lib/.dir
set -e; \
- VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
{ echo '# This file is automatically generated, do not edit!'; \
echo '#'; \
echo ''; \
echo "ENABLE_SHARED_FILE_STORAGE = $(ENABLE_SHARED_FILE_STORAGE)"; \
echo "IALLOCATOR_SEARCH_PATH = [$(IALLOCATOR_SEARCH_PATH)]"; \
echo "KVM_PATH = '$(KVM_PATH)'"; \
+ echo "IP_PATH = '$(IP_PATH)'"; \
echo "SOCAT_PATH = '$(SOCAT)'"; \
echo "SOCAT_USE_ESCAPE = $(SOCAT_USE_ESCAPE)"; \
echo "SOCAT_USE_COMPRESS = $(SOCAT_USE_COMPRESS)"; \
echo "CONFD_USER = '$(CONFD_USER)'"; \
echo "CONFD_GROUP = '$(CONFD_GROUP)'"; \
echo "NODED_USER = '$(NODED_USER)'"; \
- echo "VCS_VERSION = '$$VCSVER'"; \
+ echo "NODED_GROUP = '$(NODED_GROUP)'"; \
echo "DISK_SEPARATOR = '$(DISK_SEPARATOR)'"; \
+ if [ "$(HTOOLS)" ]; then \
+ echo "HTOOLS = True"; \
+ else \
+ echo "HTOOLS = False"; \
+ fi; \
+ } > $@
+
+lib/_vcsversion.py: Makefile vcs-version | lib/.dir
+ set -e; \
+ VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
+ { echo '# This file is automatically generated, do not edit!'; \
+ echo '#'; \
+ echo ''; \
+ echo '"""Build-time VCS version number for Ganeti.'; \
+ echo '';\
+ echo 'This file is autogenerated by the build process.'; \
+ echo 'For any changes you need to re-run ./configure (and'; \
+ echo 'not edit by hand).'; \
+ echo ''; \
+ echo '"""'; \
+ echo ''; \
+ echo '# pylint: disable-msg=C0301,C0324'; \
+ echo '# because this is autogenerated, we do not want'; \
+ echo '# style warnings' ; \
+ echo ''; \
+ echo "VCS_VERSION = '$$VCSVER'"; \
} > $@
$(REPLACE_VARS_SED): Makefile
echo '# Temporarily alias commands until bash completion'; \
echo '# generator is changed'; \
echo 'if hasattr(main, "commands"):'; \
- echo ' commands = main.commands # pylint: disable-msg=E1101'; \
+ echo ' commands = main.commands # pylint: disable-msg=E1101'; \
+ echo 'if hasattr(main, "aliases"):'; \
+ echo ' aliases = main.aliases # pylint: disable-msg=E1101'; \
echo; \
echo 'if __name__ == "__main__":'; \
echo ' sys.exit(main.Main())'; \
if test -n "$$error"; then exit 1; else exit 0; fi; \
}
-check-local: check-dirs
+.PHONY: check-local
+check-local: check-dirs $(BUILT_SOURCES)
$(CHECK_PYTHON_CODE) $(check_python_code)
$(CHECK_VERSION) $(VERSION) $(top_srcdir)/NEWS
$(CHECK_NEWS) < $(top_srcdir)/NEWS
+ PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(CHECK_IMPORTS) . $(standalone_python_modules)
+ expver=$(VERSION_MAJOR).$(VERSION_MINOR); \
+ if test "`head -n 1 $(top_srcdir)/README`" != "Ganeti $$expver"; then \
+ echo "Incorrect version in README, expected $$expver"; \
+ exit 1; \
+ fi; \
+ for file in doc/iallocator.rst doc/hooks.rst; do \
+ if test "`sed -ne '4 p' $(top_srcdir)/$$file`" != \
+ "Documents Ganeti version $$expver"; then \
+ echo "Incorrect version in $$file, expected $$expver"; \
+ exit 1; \
+ fi; \
+ done
+
+.PHONY: hs-check
+hs-check: htools/test
+ @rm -f test.tix
+ ./htools/test
+
+# E111: indentation is not a multiple of four
+# E261: at least two spaces before inline comment
+# E501: line too long (80 characters)
+PEP8_IGNORE = E111,E261,E501
+
+# For excluding pep8 expects filenames only, not whole paths
+PEP8_EXCLUDE = $(subst $(space),$(comma),$(strip $(notdir $(BUILT_PYTHON_SOURCES))))
.PHONY: lint
lint: $(BUILT_SOURCES)
@test -n "$(PYLINT)" || { echo 'pylint' not found during configure; exit 1; }
+ if test -z "$(PEP8)"; then \
+ echo '"pep8" not found during configure' >&2; \
+ else \
+ $(PEP8) --repeat --ignore='$(PEP8_IGNORE)' --exclude='$(PEP8_EXCLUDE)' \
+ $(lint_python_code); \
+ fi
$(PYLINT) $(LINT_OPTS) $(lint_python_code)
cd $(top_srcdir)/qa && \
PYTHONPATH=$(abs_top_srcdir) $(PYLINT) $(LINT_OPTS) \
@test -n "$(HADDOCK)" || \
{ echo 'haddock' not found during configure; exit 1; }
rm -rf $(APIDOC_HS_DIR)/*
- @mkdir_p@ $(APIDOC_HS_DIR)/Ganeti/HTools
+ @mkdir_p@ $(APIDOC_HS_DIR)/Ganeti/HTools/Program
$(HSCOLOUR) -print-css > $(APIDOC_HS_DIR)/Ganeti/hscolour.css
ln -s ../hscolour.css $(APIDOC_HS_DIR)/Ganeti/HTools/hscolour.css
set -e ; \
then OPTGHC="--optghc=$(HTOOLS_NOCURL)"; \
else OPTGHC=""; \
fi; \
- RELSRCS="$(HS_LIB_SRCS:htools/%=%)"; \
+ if [ "$(HTOOLS_PARALLEL3)" ]; \
+ then OPTGHC="$$OPTGHC --optghc=$(HTOOLS_PARALLEL3)"; \
+ fi; \
+ RELSRCS="$(HS_LIB_SRCS:htools/%=%) $(HS_BUILT_SRCS:htools/%=%)"; \
for file in $$RELSRCS; do \
hfile=`echo $$file|sed 's/\\.hs$$//'`.html; \
$(HSCOLOUR) -css -anchor $$file > ../$(APIDOC_HS_DIR)/$$hfile ; \
.PHONY: hs-coverage
hs-coverage: $(haskell_tests)
cd htools && rm -f *.tix *.mix && ./test
- mkdir -p $(COVERAGE_HS_DIR)
+ @mkdir_p@ $(COVERAGE_HS_DIR)
hpc markup --destdir=$(COVERAGE_HS_DIR) htools/test $(HPCEXCL)
hpc report htools/test $(HPCEXCL)
- ln -s hpc_index.html $(COVERAGE_HS_DIR)/index.html
+ ln -sf hpc_index.html $(COVERAGE_HS_DIR)/index.html
# Special "kind-of-QA" target for htools, needs special setup (all
# tools compiled with -fhpc)