Commit Graph

84 Commits

Author SHA1 Message Date
Michal Privoznik
a156b69c35 tests: Use virTestCompareToString() more
Instead of using:

  if (STRNEQ(a, b)) {
      virTestDifference(stderr, a, b);
      ...
  }

we can use:

  if (virTestCompareToString(a, b) < ) {
      ...
  }

Generated by the following spatch:

  @@
  expression a, b;
  @@

  - if (STRNEQ(a, b)) {
  + if (virTestCompareToString(a, b) < 0) {
      ...
  -   virTestDifference(stderr, a, b);
      ...
      }

and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).

However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-12-01 14:22:39 +01:00
Peng Liang
48e8c36b05 tests: Remove unused includes
Signed-off-by: Peng Liang <tcx4c70@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-06-16 06:43:58 +02:00
Andrea Bolognani
6901d92ec4 virnetsockettest: Increase coverage
Add test cases for quotes appearing in the netcat parameter,
for the default behavior of proxy=auto where virt-ssh-helper
is used if available, and for proxy=native.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:24 +01:00
Andrea Bolognani
5068a76493 virnetsockettest: Allow changing the proxy parameter
Currently the test cases all follow the proxy=auto behavior, but
we want to add coverage for other proxy modes as well.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:15 +01:00
Andrea Bolognani
02c9948e36 virnetsockettest: Tweak input for test 7
The important part of the value we assign to "netcat" is that it
contains whitespace, so drop everything else to highlight this
fact.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:09 +01:00
Andrea Bolognani
709d190a82 virnetsockettest: Improve indentation
Having the actual script indented and the closing quote on a
separate line, like

  sh -c '
    if foo; then
      bar;
    fi
  '

makes things more readable and easier to scan visually.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:06 +01:00
Andrea Bolognani
a280b9282f virnetsockettest: Move opening quote
Make this test case consistent with all the other ones.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:05 +01:00
Andrea Bolognani
5bf9902012 virnetsockettest: Drop unnecessary backslash
No need to escape a single quote.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-02-14 11:32:03 +01:00
Michal Privoznik
87a43a907f lib: Use g_clear_pointer() more
This change was generated using the following spatch:

  @ rule1 @
  expression a;
  identifier f;
  @@
    <...
  - f(*a);
    ... when != a;
  - *a = NULL;
  + g_clear_pointer(a, f);
    ...>

  @ rule2 @
  expression a;
  identifier f;
  @@
    <...
  - f(a);
    ... when != a;
  - a = NULL;
  + g_clear_pointer(&a, f);
    ...>

Then, I left some of the changes out, like tools/nss/ (which
doesn't link with glib) and put back a comment in
qemuBlockJobProcessEventCompletedActiveCommit() which coccinelle
decided to remove (I have no idea why).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-02-08 08:42:07 +01:00
Michal Privoznik
44d8324f13 virnetsocket: Don't free virCommand in virNetSocketNewConnectCommand()
The aim of virNetSocketNewConnectCommand() is to execute passed
command and attach socket pair/pipe to it so that client socket
can be opened (this is used for connections with alternative
transports, e.g. ssh). The virCommand is created in a caller and
then passed to virNetSocketNewConnectCommand() where it is freed
using virCommandFree(). This approach is wrong on two levels:

1) The deallocation happens on a different level than allocation,
2) There's a WIN32 stub that just reports an error and doesn't
   free the command.

However, with g_autoptr() trickery the command can be freed in
caller.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2021-10-15 16:03:22 +02:00
Ján Tomko
526551ac0a tests: vir: use g_autofree
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
2021-09-09 18:06:13 +02:00
Ján Tomko
8120df4e85 virnetsockettest: refactor checkProtocols
Reduce variable scope, use g_auto and remove pointless labels.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2021-09-08 16:19:55 +02:00
Daniel P. Berrangé
48f66cfe3e rpc: remove "spawnDaemon" parameter
The "spawnDaemon" and "binary" parameters are co-dependant, with the
latter non-NULL, if-and-only-if the former is true. Getting rid of the
"spawnDaemon" parameter simplifies life for the callers and eliminates
an error checking scenario.

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2021-06-04 11:42:59 +01:00
Michal Privoznik
c8238579fb lib: Drop internal virXXXPtr typedefs
Historically, we declared pointer type to our types:

  typedef struct _virXXX virXXX;
  typedef virXXX *virXXXPtr;

But usefulness of such declaration is questionable, at best.
Unfortunately, we can't drop every such declaration - we have to
carry some over, because they are part of public API (e.g.
virDomainPtr). But for internal types - we can do drop them and
use what every other C project uses 'virXXX *'.

This change was generated by a very ugly shell script that
generated sed script which was then called over each file in the
repository. For the shell script refer to the cover letter:

https://listman.redhat.com/archives/libvir-list/2021-March/msg00537.html

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2021-04-13 17:00:38 +02:00
Ján Tomko
5eed9a6ab3 tests: use g_new0 instead of VIR_ALLOC_N
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2020-09-23 16:49:01 +02:00
Daniel P. Berrangé
f8ec7c842d rpc: use new virt-ssh-helper binary for remote tunnelling
This wires up support for using the new virt-ssh-helper binary with the ssh,
libssh and libssh2 protocols.

The new binary will be used preferentially if it is available in $PATH,
otherwise we fall back to traditional netcat.

The "proxy" URI parameter can be used to force use of netcat e.g.

  qemu+ssh://host/system?proxy=netcat

or the disable fallback e.g.

  qemu+ssh://host/system?proxy=native

With use of virt-ssh-helper, we can now support remote session URIs

  qemu+ssh://host/session

and this will only use virt-ssh-helper, with no fallback. This also lets
the libvirtd process be auto-started, and connect directly to the
modular daemons, avoiding use of virtproxyd back-compat tunnelling.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-09-09 16:46:22 +01:00
Daniel P. Berrangé
019b13dd20 rpc: merge logic for generating remote SSH shell script
Three parts of the code all build up the same SSH shell script
snippet for remote tunneling the RPC protocol, but in slightly
different ways. Combine them all into one helper method in the
virNetClient code, since this logic doesn't really belong in
the virNetSocket code.

Note that the this change means the shell snippet is passed to
the SSH binary as a single arg, instead of three separate args,
but this is functionally identical, as the three separate args
were combined into one already when passed to the remote system.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-09-09 16:46:22 +01:00
Michal Privoznik
95b9db4ee2 lib: Prefer WITH_* prefix for #if conditionals
Currently, we are mixing: #if HAVE_BLAH with #if WITH_BLAH.
Things got way better with Pavel's work on meson, but apparently,
mixing these two lead to confusing and easy to miss bugs (see
31fb929eca for instance). While we were forced to use HAVE_
prefix with autotools, we are free to chose our own prefix with
meson and since WITH_ prefix appears to be more popular let's use
it everywhere.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2020-09-02 10:28:10 +02:00
Ján Tomko
fd7644cba9 tests: use VIR_WARNINGS_NO_DECLARATION_AFTER_STATEMENT
Some test rely too much on declaring variables in the middle
of the function. Use the macro to locally suppress the warning

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-08-25 19:03:13 +02:00
Andrea Bolognani
deceb1e09f tests: Minimize variable scope
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-07-15 12:52:24 +02:00
Andrea Bolognani
efe6429910 tests: Don't assume IPv4 connectivity is available
If the host doesn't have a single IPv4 address assigned to any of
its interfaces, not even the loopback one, then virnetsockettest
will fail with

  Cannot identify IPv4/6 availability

because, while the IPv6 bind attempt is conditional, the IPv4 one
is not, and in this case it will always fail.

This commit is better viewed with 'git show -w'.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-07-15 12:52:20 +02:00
Ján Tomko
44256e3f2c tests: include unistd.h instead of virutil.h
These tests do not use anything from virutil.h
apart from the transitive include.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
2020-02-24 23:15:49 +01:00
Daniel P. Berrangé
21fa70e2f6 tests: conditionalize use of SIGPIPE
SIGPIPE is not available on the Windows platform.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-01-29 14:51:40 +00:00
Daniel P. Berrangé
fc920f704c src: convert all code to use virsocket.h
There are a large number of different header files that
are related to the sockets APIs. The virsocket.h header
includes all of the relevant headers for Windows and UNIX
in one convenient place. If virsocketaddr.h is already
included, then there's no need for virsocket.h

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-01-29 14:51:40 +00:00
Pavel Hrdina
43b01ef2d6 replace use of gnulib snprintf by g_snprintf
Glib implementation follows the ISO C99 standard so it's safe to replace
the gnulib implementation.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2019-11-15 15:07:40 +01:00
Ján Tomko
ef88698668 Use g_mkdtemp instead of mkdtemp
Prefer the GLib version to the one from gnulib.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2019-11-14 19:02:31 +01:00
Michal Privoznik
4fa804c0c7 tests: Use g_strdup_printf() instead of virAsprintf()
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
2019-11-12 16:15:59 +01:00
Ján Tomko
0d94f02455 tests: use G_GNUC_UNUSED
Use G_GNUC_UNUSED from GLib instead of ATTRIBUTE_UNUSED.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2019-10-15 11:25:25 +02:00
Daniel P. Berrangé
76d31244c5 rpc: fix escaping of shell path for netcat binary
Consider having a nc binary in the path with a space in its name,
for example '/tmp/fo o/nc'

This results in libvirt running SSH with the following arg value

  "'if ''/tmp/fo o/nc'' -q 2>&1 | grep \"requires
    an argument\" >/dev/null 2>&1; then ARG=-q0;
    else ARG=;fi;''/tmp/fo o/nc'' $ARG -U
    /var/run/libvirt/libvirt-sock'"

The use of the single quote escaping was introduced by

  commit 6ac6238de3
  Author: Guido Günther <agx@sigxcpu.org>
  Date:   Thu Oct 13 21:49:01 2011 +0200

    Use virBufferEscapeShell in virNetSocketNewConnectSSH

    to escape the netcat command since it's passed to the shell. Adjust
    expected test case output accordingly.

While the intention of this change was good, the result is broken as it
is still underquoted.

On the SSH server side, SSH itself runs the command via the shell.
Our command is then invoking the shell again. Thus we see

$ virsh -c qemu+ssh://root@domokun/system?netcat=%2Ftmp%2Ffo%20o%2Fnc list
error: failed to connect to the hypervisor
error: End of file while reading data: sh: /tmp/fo: No such file or directory: Input/output error

With the second level of escaping added we can now successfully use a nc
binary with a space in the path.

The original test case added was misleading as it illustrated using a
binary path of 'nc -4' which is not a path, it is a command with a
separate argument, which is getting interpreted as a path.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2019-10-01 12:57:07 +01:00
Daniel P. Berrangé
1939bcd539 rpc: always pass "-T -e none" args to ssh
Way back in the past, the "no_tty=1" option was added for the remote
driver to disable local password prompting by disabling use of the local
tty:

  commit b32f429849
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Fri Sep 21 20:17:09 2007 +0000

    Added a no_tty param to remote URIs to stop SSH prompting for password

This was done by adding "-T -o BatchMode=yes -e none" args to ssh. This
achieved the desired results but is none the less semantically flawed
because it is mixing up config parameters for the local tty vs the
remote tty.

The "-T" arg stops allocation of a TTY on the remote host. This is good
for all libvirt SSH tunnels as we never require a TTY for our usage
model, so we should have just passed this unconditionally.

The "-e none" option disables the escape character for sessions with a
TTY. If we pass "-T" this is not required, but it also not harmful to
add it, so we should just pass it unconditionally too.

Only the "-o BatchMode=yes" option is related to disabling local
password prompts and thus needs control via the no_tty URI param.

Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2019-07-11 15:26:54 +01:00
Peter Krempa
f785318187 Revert "Include unistd.h directly by files using it"
This reverts commit a5e1602090.

Getting rid of unistd.h from our headers will require more work than
just fixing the broken mingw build. Revert it until I have a more
complete proposal.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
2019-04-10 12:26:32 +02:00
Peter Krempa
a5e1602090 Include unistd.h directly by files using it
util/virutil.h bogously included unistd.h. Drop it and replace it by
including it directly where needed.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2019-04-10 09:12:04 +02:00
Daniel P. Berrangé
600462834f Remove all Author(s): lines from source file headers
In many files there are header comments that contain an Author:
statement, supposedly reflecting who originally wrote the code.
In a large collaborative project like libvirt, any non-trivial
file will have been modified by a large number of different
contributors. IOW, the Author: comments are quickly out of date,
omitting people who have made significant contribitions.

In some places Author: lines have been added despite the person
merely being responsible for creating the file by moving existing
code out of another file. IOW, the Author: lines give an incorrect
record of authorship.

With this all in mind, the comments are useless as a means to identify
who to talk to about code in a particular file. Contributors will always
be better off using 'git log' and 'git blame' if they need to  find the
author of a particular bit of code.

This commit thus deletes all Author: comments from the source and adds
a rule to prevent them reappearing.

The Copyright headers are similarly misleading and inaccurate, however,
we cannot delete these as they have legal meaning, despite being largely
inaccurate. In addition only the copyright holder is permitted to change
their respective copyright statement.

Reviewed-by: Erik Skultety <eskultet@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-13 16:08:38 +00:00
Erik Skultety
5165ff0971 src: More cleanup of some system headers already contained in internal.h
All of the ones being removed are pulled in by internal.h. The only
exception is sanlock which expects the application to include <stdint.h>
before sanlock's headers, because sanlock prototypes use fixed width
int, but they don't include stdint.h themselves, so we have to leave
that one in place.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
Acked-by: Michal Privoznik <mprivozn@redhat.com>
2018-09-20 10:16:39 +02:00
Jiri Denemark
602ecdf2ab Drop \n at the end of VIR_DEBUG messages
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2018-09-19 14:05:59 +02:00
John Ferlan
a0ba31c006 test: Remove possible infinite loop in virnetsockettest
Commit 39015a6f3 modified the test to be more reliable/realistic,
but without checking the return status of virEventRunDefaultImpl
it's possible that the test could run infinitely.

Found by Coverity

Signed-off-by: John Ferlan <jferlan@redhat.com>
ACKed-by: Michal Privoznik <mprivozn@redhat.com>
2018-09-11 10:47:20 -04:00
Daniel P. Berrangé
39015a6f3a tests: rewrite socket to do something sensible and reliable
The current socket test is rather crazy in that it sets up a server
listening for sockets and then runs a client connect call, relying on
the fact that the kernel will accept this despite the application
not having called accept() yet. It then closes the client socket and
calls accept() on the server. On Linux accept() will always see that
the client has gone and so skip the rest of the code. On FreeBSD,
however, the accept sometimes succeeds, causing us to then go into
code that attempts to read and write to the client which will fail
aborting the test. The accept() never succeeds on FreeBSD guests
with a single CPU, but as you add more CPUs, accept() becomes more and
more likely to succeed, giving a 100% failure rate for the test when
using 8 CPUs.

This completely rewrites the test so that it is avoids this designed in
race condition. We simply spawn a background thread to act as the
client, which will read a byte from the server and write it back again.
The main thread can now properly listen and accept the client in a
synchronous manner avoiding any races.

Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-09-04 13:22:06 +01:00
Daniel P. Berrangé
9e2fad87b4 tests: merge code for UNIX and TCP socket testing
The test code for UNIX and TCP sockets will need to be rewritten and
extended later, and will benefit from code sharing.

Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-09-04 13:20:12 +01:00
Martin Kletzander
21864e28ad tests: Fix virnetsockettest after SSH command line changes
Commit e4cb850081 changed the way ssh command line is created by
adding '--' before the hostname in order to fix a potential security
flaw.  However it failed to modify the tests, so let's do that.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2017-08-30 10:50:17 +02:00
Andrea Bolognani
4ceac4bf29 tests: Rename VIRT_TEST_* macros to VIR_TEST_*
We use the "vir" prefix pretty consistently in our
APIs, both external and internal, which made these
macros stood out.
2017-04-04 17:30:03 +02:00
Ján Tomko
ea537e7b36 Add SASL to virNetSocket{Local,Remote}AddrString
Rename them to virNetSocket{Local,Remote}AddrStringSASL
to make their format more obvious.
2016-06-23 22:23:21 +02:00
Ján Tomko
42362c9166 virnetsockettest: fix error messages 2016-06-23 22:23:21 +02:00
Ján Tomko
2da6a13e5f Introduce virNetSocketRemoteAddrStringURI
It will return the socket address and port in a URI-like
format: [::1]:1234
Add a test case to virnetsockettest.
2016-06-23 22:21:36 +02:00
Ján Tomko
0f7eeb20ad Revert "virnetsocket: Provide socket address format in a more standard form"
This partially reverts commit 9b45c9f049.

It changed the default format of socket address from the one SASL
requires, but did not adjust all the callers.

It also removed the test coverage for it.

Revert most of the changes except the virSocketAddrFormatFull support
for URI-formatted strings.

This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1345743 while
reverting the format used by virt-admin's client-info command from
the URI one to the SASL one.

https://bugzilla.redhat.com/show_bug.cgi?id=1345743
2016-06-23 22:15:06 +02:00
Tomáš Ryšavý
062ea148a0 Rename virtTestDifference to virTestDifference.
This function doesn't follow our convention of naming functions.
2016-06-08 11:23:12 -04:00
Tomáš Ryšavý
cd7dd1508d tests: Rename virtTestRun to virTestRun.
This function doesn't follow our convention of naming functions.
2016-06-08 11:23:12 -04:00
Erik Skultety
9b45c9f049 virnetsocket: Provide socket address format in a more standard form
Our socket address format is in a rather non-standard format and that is
because sasl library requires the IP address and service to be delimited by a
semicolon. The string form is a completely internal matter, however once the
admin interfaces to retrieve client identity information are merged, we should
return the socket address string in a common format, e.g. format defined by
URI rfc-3986, i.e. the IP address and service are delimited by a colon and
in case of an IPv6 address, square brackets are added:

Examples:
    127.0.0.1:1234
    [::1]:1234

This patch changes our default format to the one described above, while adding
separate methods to request the non-standard SASL format using semicolon as a
delimiter.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
2016-05-03 15:52:50 +02:00
Jiri Denemark
e4ee043636 Remove new lines from log messages
VIR_DEBUG and VIR_WARN will automatically add a new line to the message,
having "\n" at the end or at the beginning of the message results in
empty lines.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
2015-11-04 13:09:35 +01:00
Ishmanpreet Kaur Khera
32cee5b2f0 Avoid using !STREQ and !STRNEQ
We have macros for both positive and negative string matching.
Therefore there is no need to use !STREQ or !STRNEQ. At the same
time as we are dropping this, new syntax-check rule is
introduced to make sure we won't introduce it again.

Signed-off-by: Ishmanpreet Kaur Khera <khera.ishman@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2015-10-21 15:03:35 +02:00
Daniel P. Berrange
43c0a84cda rpc: add API for checking IPv4/6 availability
The socket test suite has a function for checking if IPv4
or IPv6 are available, and returning a free socket. The
first bit of that will be needed in another test, so pull
that logic out into a separate helper method.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-06-11 12:11:18 +01:00