[libblockdev:master] Make Makefile mostly automatic.

Anne Mulhern amulhern at redhat.com
Tue Jul 1 14:19:26 UTC 2014





----- Original Message -----
> From: "Vratislav Podzimek" <vpodzime at redhat.com>
> To: "anaconda patch review" <anaconda-patches at lists.fedorahosted.org>
> Sent: Tuesday, July 1, 2014 2:12:30 AM
> Subject: Re: [libblockdev:master] Make Makefile mostly automatic.
> 
> On Mon, 2014-06-30 at 16:55 -0400, mulhern wrote:
> > There is still room for sorting out variables for flags, etc, and of course
> > for autotooling.
> > 
> > Other changes are:
> > - Making every TESTING_* macro just TESTING for ease in automation.
> My first idea was to go with TESTING, but then I hit a problem with two
> or more 'main()' functions defined when multiple sources were combined
> into a single binary (lvm.c and sizes.c) originally. While this is not
> an issue now with the utils library, it will probably come back with the
> FS plugin where a single plugin will be compiled from fs_ext.c,
> fs_xfs.c, etc. Any ideas? Would "ifndef TESTING" guard solve the issue
> and would TESTING become defined based on the ordering of files passed
> to gcc? (i.e. wanna test lvm.c -> I pass lvm.c sizes.c, wanna test
> sizes.c -> I pass sizes.c lvm.c)
> 

That seems very tricky. In this situation I would probably try
to re-architecture my testing so that the test files included the
source files instead of vice-versa. I'm sure that brings in a chunk
of troubles, but it definitely gets rid of the macro problem.

If I was absolutely determined to stick w/ the same architecture,
I'ld probably switch back to distinct macros and try to do something
wth the $* automatic variable.

> > - reversing the order of includes in src/lib/blockdev.c to
> > enable compilation w/out the include in src/lib/blockdev.h.
> > - A few small fixes indicated by warning/error messages.
> > 
> > Signed-off-by: mulhern <amulhern at redhat.com>
> > ---
> >  Makefile                 | 155
> >  +++++++++++++++++++++--------------------------
> >  src/lib/blockdev.c       |  11 ++--
> >  src/lib/blockdev.h       |   1 -
> >  src/lib/plugin_apis/dm.h |   2 +-
> >  src/plugins/loop.c       |   2 +-
> >  src/plugins/lvm.c        |   2 +-
> >  src/plugins/swap.c       |   2 +-
> >  src/plugins/test_loop.c  |   2 +-
> >  src/plugins/test_lvm.c   |   3 +-
> >  src/plugins/test_swap.c  |   2 +-
> >  src/utils/sizes.c        |   2 +-
> >  src/utils/test_sizes.c   |   2 +-
> >  12 files changed, 82 insertions(+), 104 deletions(-)
> > 
> > diff --git a/Makefile b/Makefile
> > index fe4392f..8eb82fb 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -1,105 +1,86 @@
> > -UTILS_FILES = src/utils/sizes.c src/utils/sizes.h src/utils/exec.c
> > src/utils/exec.h src/utils/utils.h
> > -LVM_PLUGIN_FILES = src/plugins/lvm.h src/plugins/lvm.c
> > -SWAP_PLUGIN_FILES = src/plugins/swap.h src/plugins/swap.c
> > -LOOP_PLUGIN_FILES = src/plugins/loop.h src/plugins/loop.c
> > -CRYPTO_PLUGIN_FILES = src/plugins/crypto.h src/plugins/crypto.c
> > -MPATH_PLUGIN_FILES = src/plugins/mpath.h src/plugins/mpath.c
> > -DM_PLUGIN_FILES = src/plugins/dm.h src/plugins/dm.c
> > -LIBRARY_FILES = src/lib/blockdev.c src/lib/blockdev.h src/lib/plugins.h
> > src/lib/plugin_apis/lvm.h
> > -
> > -build-plugins: ${LVM_PLUGIN_FILES} ${SWAP_PLUGIN_FILES}
> > ${LOOP_PLUGIN_FILES} ${MPATH_PLUGIN_FILES}
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/utils/ -I src/plugins/ \
> > -		`pkg-config --cflags glib-2.0 gobject-2.0` src/plugins/lvm.c
> > -	gcc -shared -o src/plugins/libbd_lvm.so lvm.o
> > -
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/plugins/ -I src/utils/ \
> > -		`pkg-config --cflags glib-2.0` src/plugins/swap.c
> > -	gcc -shared -o src/plugins/libbd_swap.so swap.o
> > -
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/plugins/ -I src/utils/ \
> > -		`pkg-config --cflags glib-2.0` src/plugins/loop.c
> > -	gcc -shared -o src/plugins/libbd_loop.so loop.o
> > -
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/plugins/ -lm `pkg-config --libs
> > --cflags glib-2.0 libcryptsetup`\
> > -		src/plugins/crypto.c
> > -	gcc -shared -o src/plugins/libbd_crypto.so crypto.o
> > -
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/plugins/ -I src/utils/ \
> > -		`pkg-config --cflags glib-2.0` src/plugins/mpath.c
> > -	gcc -shared -o src/plugins/libbd_mpath.so mpath.o
> > -
> > -	gcc -c -Wall -Wextra -Werror -fPIC -I src/plugins/ -I src/utils/ \
> > -		`pkg-config --cflags glib-2.0` src/plugins/dm.c
> > -	gcc -shared -o src/plugins/libbd_dm.so dm.o
> > -
> > -generate-boilerplate-code: src/lib/plugin_apis/lvm.h
> > src/lib/plugin_apis/swap.h
> > -	./boilerplate_generator.py src/lib/plugin_apis/lvm.h >
> > src/lib/plugin_apis/lvm.c
> > -	./boilerplate_generator.py src/lib/plugin_apis/swap.h >
> > src/lib/plugin_apis/swap.c
> > -	./boilerplate_generator.py src/lib/plugin_apis/loop.h >
> > src/lib/plugin_apis/loop.c
> > -	./boilerplate_generator.py src/lib/plugin_apis/crypto.h >
> > src/lib/plugin_apis/crypto.c
> > -	./boilerplate_generator.py src/lib/plugin_apis/mpath.h >
> > src/lib/plugin_apis/mpath.c
> > -	./boilerplate_generator.py src/lib/plugin_apis/dm.h >
> > src/lib/plugin_apis/dm.c
> > -
> > -build-utils: ${UTILS_FILES}
> > -	gcc -c -Wall -Wextra -Werror -fPIC `pkg-config --cflags glib-2.0` -I
> > src/utils/ \
> > -        src/utils/sizes.c
> > -	gcc -c -Wall -Wextra -Werror -fPIC `pkg-config --cflags glib-2.0` -I
> > src/utils/ \
> > -        src/utils/exec.c
> > -	gcc -shared -o src/utils/libbd_utils.so sizes.o exec.o
> > -
> > -build-library: generate-boilerplate-code ${LIBRARY_FILES}
> > -	gcc -fPIC -c `pkg-config --libs --cflags glib-2.0` -ldl
> > src/lib/blockdev.c
> > -	gcc -shared -o src/lib/libblockdev.so blockdev.o
> > -
> > -build-introspection-data: build-utils build-library ${LIBRARY_FILES}
> > -	LD_LIBRARY_PATH=src/lib/:src/utils/ g-ir-scanner `pkg-config --cflags
> > --libs glib-2.0 gobject-2.0 libcryptsetup` --library=blockdev -I src/lib/
> > -L src/utils -lbd_utils -L src/lib/ --identifier-prefix=BD
> > --symbol-prefix=bd --namespace BlockDev --nsversion=1.0 -o
> > BlockDev-1.0.gir --warn-all src/lib/blockdev.h src/lib/blockdev.c
> > src/lib/plugins.h src/lib/plugin_apis/lvm.h src/lib/plugin_apis/swap.h
> > src/lib/plugin_apis/loop.h src/lib/plugin_apis/crypto.h
> > src/lib/plugin_apis/mpath.h src/lib/plugin_apis/dm.h
> > -	g-ir-compiler -o BlockDev-1.0.typelib BlockDev-1.0.gir
> > +LIBRARY_FILES := src/lib/blockdev.c src/lib/blockdev.h src/lib/plugins.h
> > +UTILS_SOURCES := src/utils/exec.c src/utils/sizes.c
> > +UTILS_OBJS := $(patsubst %.c,%.o,${UTILS_SOURCES})
> > +PLUGIN_HEADER_FILES := $(wildcard src/lib/plugin_apis/*.h)
> > +PLUGIN_SOURCE_FILES := $(patsubst %.h,%.c,${PLUGIN_HEADER_FILES})
> > +PLUGIN_SOURCES := src/plugins/crypto.c src/plugins/dm.c src/plugins/loop.c
> > src/plugins/lvm.c src/plugins/mpath.c src/plugins/swap.c
> > +PLUGIN_OBJS := $(patsubst %.c,%.o,${PLUGIN_SOURCES})
> > +PLUGIN_LIBS := $(addprefix src/plugins/,$(patsubst %.c,libbd_%.so,$(notdir
> > ${PLUGIN_SOURCES})))
> > +GLIB_INCLUDES := `pkg-config --cflags glib-2.0`
> > +GOBJECT_INCLUDES := `pkg-config --cflags gobject-2.0`
> > +LIBCRYPTSETUP_INCLUDES := `pkg-config --cflags libcryptsetup`
> >  
> > -test-sizes: ${SIZES_FILES}
> > -	gcc -Wall -DTESTING_SIZES -o test_sizes -I src/utils/ -lm `pkg-config
> > --libs --cflags glib-2.0`\
> > -		src/utils/sizes.c
> > -	@echo "***Running tests***"
> > -	./test_sizes
> > -	@rm test_sizes
> > +test_%.o: %.c test_%.c %.h
> > +	gcc -c -Wall -Wextra -Werror -DTESTING -o $@ -I src/utils/ -I src/plugins
> > ${GLIB_INCLUDES} $<
> >  
> > -test-lvm-plugin: ${LVM_PLUGIN_FILES} build-utils
> > -	gcc -DTESTING_LVM -o test_lvm_plugin -I src/utils/ -I src/plugins/ -I
> > src/utils/ \
> > -		-L src/utils/ -lbd_utils -lm `pkg-config --libs --cflags glib-2.0
> > gobject-2.0`\
> > -		src/plugins/lvm.c
> > -	@echo "***Running tests***"
> > -	LD_LIBRARY_PATH=src/utils/	./test_lvm_plugin
> > -	@rm test_lvm_plugin
> >  
> > -test-swap-plugin: ${SWAP_PLUGIN_FILES} build-utils
> > -	gcc -DTESTING_SWAP -o test_swap_plugin -I src/plugins/ -I src/utils/ -L
> > src/utils/ -lbd_utils \
> > -		`pkg-config --libs --cflags glib-2.0` src/plugins/swap.c
> > +%.o: %.c %.h
> > +	gcc -c -Wall -Wextra -Werror -fPIC -o $@ -I src/utils/ ${GLIB_INCLUDES}
> > $<
> > +
> > +test_%: test_%.o ${UTILS_OBJS}
> > +	gcc -o $@ -lm `pkg-config --libs glib-2.0` $^
> > +
> > +test-%: src/plugins/test_%
> >  	@echo "***Running tests***"
> > -	LD_LIBRARY_PATH=src/utils/ ./test_swap_plugin
> > -	@rm test_swap_plugin
> > +	./$<
> >  
> > -test-loop-plugin: ${LOOP_PLUGIN_FILES} build-utils
> > -	gcc -DTESTING_LOOP -o test_loop_plugin -I src/plugins/ -I src/utils/ -L
> > src/utils/ -lbd_utils \
> > -		`pkg-config --libs --cflags glib-2.0` src/plugins/loop.c
> > +src/utils/test_sizes: src/utils/test_sizes.o
> > +	gcc -o $@ -lm `pkg-config --libs glib-2.0` $<
> > +
> > +test-sizes: src/utils/test_sizes
> >  	@echo "***Running tests***"
> > -	LD_LIBRARY_PATH=src/utils/ ./test_loop_plugin
> > -	@rm test_loop_plugin
> > +	./$<
> > +
> > +src/lib/test_blockdev.o: src/lib/blockdev.c src/lib/test_blockdev.c
> > src/lib/blockdev.h ${PLUGIN_SOURCE_FILES}
> > +	gcc -c -Wextra -Werror -DTESTING -o $@ -I src/utils/ -I src/plugins
> > ${GLIB_INCLUDES} $<
> >  
> > -test-library: generate-boilerplate-code build-plugins
> > -	gcc -DTESTING_LIB -o test_library `pkg-config --libs --cflags glib-2.0
> > gobject-2.0` -ldl src/lib/blockdev.c
> > +src/lib/test_library: src/lib/test_blockdev.o ${PLUGIN_LIBS}
> > +	gcc -o $@ -ldl `pkg-config --libs glib-2.0 gobject-2.0` $<
> > +
> > +test-library: src/lib/test_library
> >  	@echo "***Running tests***"
> > -	LD_LIBRARY_PATH=src/plugins/ ./test_library
> > -	@rm test_library
> > +	LD_LIBRARY_PATH=src/plugins/ ./$<
> > +
> > +test-plugins: test-loop test-lvm test-swap
> >  
> > -test-from-python: build-library build-plugins build-introspection-data
> > +libbd_%.so: %.o
> > +	gcc -shared -fPIC -o $@ $<
> > +
> > +src/utils/libbd_utils.so: ${UTILS_OBJS}
> > +	gcc -shared -fPIC -o src/utils/libbd_utils.so $^
> > +
> > +src/lib/plugin_apis/%.c: src/lib/plugin_apis/%.h
> > +	./boilerplate_generator.py $< > $@
> > +
> > +src/lib/blockdev.o: ${LIBRARY_FILES} ${PLUGIN_SOURCE_FILES}
> > +	gcc -fPIC -c ${GLIB_INCLUDES} $< -o $@
> > +
> > +src/lib/libblockdev.so: src/lib/blockdev.o
> > +	gcc -shared -fPIC -o $@ $<
> > +
> > +build-introspection-data: src/utils/libbd_utils.so src/lib/libblockdev.so
> > ${LIBRARY_FILES}
> > +	LD_LIBRARY_PATH=src/lib/:src/utils/ g-ir-scanner `pkg-config --cflags
> > --libs glib-2.0 gobject-2.0 libcryptsetup` --library=blockdev -I src/lib/
> > -L src/utils -lbd_utils -L src/lib/ --identifier-prefix=BD
> > --symbol-prefix=bd --namespace BlockDev --nsversion=1.0 -o
> > BlockDev-1.0.gir --warn-all ${LIBRARY_FILES} ${PLUGIN_HEADER_FILES}
> > +	g-ir-compiler -o BlockDev-1.0.typelib BlockDev-1.0.gir
> > +
> > +test-from-python: src/lib/libblockdev.so ${PLUGIN_LIBS}
> > build-introspection-data
> >  	GI_TYPELIB_PATH=. LD_LIBRARY_PATH=src/plugins/:src/lib/ python -c 'from
> >  	gi.repository import BlockDev; BlockDev.init(None); print
> >  	BlockDev.lvm_get_max_lv_size()'
> >  
> > -run-ipython: build-library build-plugins build-introspection-data
> > +run-ipython: src/lib/libblockdev.so ${PLUGIN_LIBS}
> > build-introspection-data
> >  	GI_TYPELIB_PATH=. LD_LIBRARY_PATH=src/plugins/:src/lib/:src/utils/
> >  	ipython
> >  
> > -run-root-ipython: build-library build-plugins build-introspection-data
> > +run-root-ipython: src/lib/libblockdev.so ${PLUGIN_LIBS}
> > build-introspection-data
> >  	sudo GI_TYPELIB_PATH=. LD_LIBRARY_PATH=src/plugins/:src/lib/:src/utils/
> >  	ipython
> >  
> > -test: build-utils build-library build-plugins build-introspection-data
> > +test: src/utils/libbd_utils.so src/lib/libblockdev.so ${PLUGIN_LIBS}
> > build-introspection-data
> >  	@echo
> >  	@sudo GI_TYPELIB_PATH=. LD_LIBRARY_PATH=src/plugins/:src/lib/:src/utils/
> >  	PYTHONPATH=.:tests/ \
> >  		python -m unittest discover -v -s tests/ -p '*_test.py'
> > +
> > +clean:
> > +	-rm BlockDev-1.0.gir
> > +	-rm BlockDev-1.0.typelib
> > +	-rm src/lib/plugin_apis/*.c
> > +	-rm src/lib/blockdev.o
> > +	-rm src/lib/libblockdev.so
> > +	-rm src/plugins/libbd_*.so
> rm src/utils/libbd_utils.so should be listed here as well.
> 
> > +	find . -name '*.o' -exec rm {} \;
> > diff --git a/src/lib/blockdev.c b/src/lib/blockdev.c
> > index 9f0fc06..47da777 100644
> > --- a/src/lib/blockdev.c
> > +++ b/src/lib/blockdev.c
> > @@ -2,20 +2,19 @@
> >  #include "blockdev.h"
> >  #include "plugins.h"
> >  
> > -#include "plugin_apis/lvm.c"
> >  #include "plugin_apis/lvm.h"
> > -#include "plugin_apis/swap.c"
> > +#include "plugin_apis/lvm.c"
> >  #include "plugin_apis/swap.h"
> > -#include "plugin_apis/loop.c"
> > +#include "plugin_apis/swap.c"
> >  #include "plugin_apis/loop.h"
> > -#include "plugin_apis/crypto.c"
> > +#include "plugin_apis/loop.c"
> >  #include "plugin_apis/crypto.h"
> > +#include "plugin_apis/crypto.c"
> >  #include "plugin_apis/mpath.c"
> >  #include "plugin_apis/mpath.h"
> >  #include "plugin_apis/dm.c"
> >  #include "plugin_apis/dm.h"
> >  
> > -
> >  /**
> >   * SECTION: libblockdev
> >   * @short_description: a library for doing low-level operations with block
> >   devices
> > @@ -113,6 +112,6 @@ gboolean bd_is_plugin_available (BDPlugin plugin) {
> >          return FALSE;
> >  }
> >  
> > -#ifdef TESTING_LIB
> > +#ifdef TESTING
> >  #include "test_blockdev.c"
> >  #endif
> > diff --git a/src/lib/blockdev.h b/src/lib/blockdev.h
> > index d487596..e02016f 100644
> > --- a/src/lib/blockdev.h
> > +++ b/src/lib/blockdev.h
> > @@ -4,7 +4,6 @@
> >  #define BD_LIB
> >  
> >  #include "plugins.h"
> > -#include "plugin_apis/lvm.h"
> >  
> >  gboolean bd_init (BDPluginSpec *force_plugins);
> >  gboolean bd_reinit (BDPluginSpec *force_plugins, gboolean replace);
> > diff --git a/src/lib/plugin_apis/dm.h b/src/lib/plugin_apis/dm.h
> > index 79bdf2d..c2c44ea 100644
> > --- a/src/lib/plugin_apis/dm.h
> > +++ b/src/lib/plugin_apis/dm.h
> > @@ -20,7 +20,7 @@ gboolean bd_dm_create_linear (gchar *map_name, gchar
> > *device, guint64 length, gc
> >   *
> >   * Returns: whether the @map_name map was successfully removed or not
> >   */
> > -gboolean bd_dm_remove (gchar *map_name);
> > +gboolean bd_dm_remove (gchar *map_name, gchar **error_message);
> >  
> >  /**
> >   * bd_dm_name_from_dm_node:
> > diff --git a/src/plugins/loop.c b/src/plugins/loop.c
> > index 0e1941d..9530289 100644
> > --- a/src/plugins/loop.c
> > +++ b/src/plugins/loop.c
> > @@ -160,6 +160,6 @@ gboolean bd_loop_teardown (gchar *loop, gchar
> > **error_message) {
> >      return success;
> >  }
> >  
> > -#ifdef TESTING_LOOP
> > +#ifdef TESTING
> >  #include "test_loop.c"
> >  #endif
> > diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
> > index b611a12..e504086 100644
> > --- a/src/plugins/lvm.c
> > +++ b/src/plugins/lvm.c
> > @@ -1221,7 +1221,7 @@ gboolean bd_lvm_thsnapshotcreate (gchar *vg_name,
> > gchar *origin_name, gchar *sna
> >      return success;
> >  }
> >  
> > -#ifdef TESTING_LVM
> > +#ifdef TESTING
> >  #include "test_lvm.c"
> >  #endif
> >  
> > diff --git a/src/plugins/swap.c b/src/plugins/swap.c
> > index f30c243..53c8929 100644
> > --- a/src/plugins/swap.c
> > +++ b/src/plugins/swap.c
> > @@ -219,6 +219,6 @@ gboolean bd_swap_swapstatus (gchar *device, gchar
> > **error_message) {
> >  }
> >  
> > 
> > -#ifdef TESTING_SWAP
> > +#ifdef TESTING
> >  #include "test_swap.c"
> >  #endif
> > diff --git a/src/plugins/test_loop.c b/src/plugins/test_loop.c
> > index 2acb4a2..a6ac235 100644
> > --- a/src/plugins/test_loop.c
> > +++ b/src/plugins/test_loop.c
> > @@ -1,6 +1,6 @@
> >  #include <glib/gprintf.h>
> >  
> > -int main (int argc, char **argv) {
> > +int main () {
> >      gchar *ret = NULL;
> >      gchar *err_msg = NULL;
> >      gboolean success = FALSE;
> > diff --git a/src/plugins/test_lvm.c b/src/plugins/test_lvm.c
> > index 1ecf76f..8029e8a 100644
> > --- a/src/plugins/test_lvm.c
> > +++ b/src/plugins/test_lvm.c
> > @@ -11,8 +11,7 @@ void print_hash_table (GHashTable *table) {
> >          g_printf("%s : %s\n", (gchar *) key, (gchar *) value);
> >  }
> >  
> > -int main (int argc, char **argv) {
> > -    gint exit_status;
> > +int main () {
> >      gchar const * const *fname = NULL;
> >      gchar *msg = NULL;
> >      gchar *stdout = NULL;
> > diff --git a/src/plugins/test_swap.c b/src/plugins/test_swap.c
> > index b3f38c5..cb8c5b3 100644
> > --- a/src/plugins/test_swap.c
> > +++ b/src/plugins/test_swap.c
> > @@ -1,6 +1,6 @@
> >  #include <glib/gprintf.h>
> >  
> > -int main (int argc, char **argv) {
> > +int main () {
> >      gboolean succ = FALSE;
> >      gchar *err_msg = NULL;
> >  
> > diff --git a/src/utils/sizes.c b/src/utils/sizes.c
> > index efb14d7..43b9ceb 100644
> > --- a/src/utils/sizes.c
> > +++ b/src/utils/sizes.c
> > @@ -37,6 +37,6 @@ gchar* bd_utils_size_human_readable (guint64 size) {
> >          return g_strdup_printf ("%.2f %sB", value, size_prefixes[i]);
> >  }
> >  
> > -#ifdef TESTING_SIZES
> > +#ifdef TESTING
> >  #include "test_sizes.c"
> >  #endif
> > diff --git a/src/utils/test_sizes.c b/src/utils/test_sizes.c
> > index 2e29887..e59206a 100644
> > --- a/src/utils/test_sizes.c
> > +++ b/src/utils/test_sizes.c
> > @@ -1,4 +1,4 @@
> > -int main (int argc, char **argv) {
> > +int main () {
> >      gchar *human = NULL;
> >      human = bd_utils_size_human_readable ((16 MiB));
> >      puts (human);
> Otherwise this looks good to me. Thanks! Just one thing I'd like to ask
> for -- is there any reasonable, straightforward and clear
> cheatsheet/overview of Makefile syntax and tricks? For example this:
> "+	./$<" made me start thinking about writing a Perl script instead of a
> Makefile cause it would be much clearer to me and in the same cryptic
> for the others, I'd say.
> 

I think the answer is No. I actually wrote something once that might be useful.
It sits on my laptop at home, so I'll send it tonight. And I've occasionally
run across other helpful things, which I'll pass on to you as I find them again.

I think the problem is that make is not all that well suited to its task,
so it gets ugly fast.
It's not just the lack of type checking, but more fundamental things like
the need to more or less statically list dependencies in the Makefile,
and so forth.
I've used ant and scons as well, but not enough to have an opinion.

For what it's worth, I'ld rather write makefiles than shell scripts :)

> Thanks!!!
> 
> --
> Vratislav Podzimek
> 
> Anaconda Rider | RHCE | Red Hat, Inc. | Brno - Czech Republic
> 
> 
> _______________________________________________
> anaconda-patches mailing list
> anaconda-patches at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
> 


More information about the anaconda-patches mailing list