Commit Graph

1638 Commits

Author SHA1 Message Date
Serge Hallyn
1aad9e44d6 ubuntu-cloud: changes to support unprivileged use
don't try to lock if using a specified tarball

The lock/subsys/lxc-ubuntu-cloud lock is to protect the tarballs
managed under /var/cache/lxc/cloud-$release.  Don't lock if we've
been handed a tarball.

fake device creation

Unprivileged users can't create devices, so bind mount null, tty, urandom
and console from the host.

Changelog:
	Jul 22: as Stéphane points out, remove a left-over debug line

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-22 12:15:43 -05:00
Serge Hallyn
460bcbd85c lxc-create: support unpriv users
Just make sure we are root if we are asked to deal with something other
than a directory, and make sure we have permission to create the
container in the given lxcpath.

The templates will need much more work.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-22 12:14:53 -05:00
Serge Hallyn
5be56973e5 templates: require running as root
Up to now lxc-create ensured that you were running as root.  Now the
templates which require root need to do it for themselves.  Templates
which do mknod definately require root.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-22 12:14:22 -05:00
Serge Hallyn
4165b2c656 teach lxc-cirros about the --rootfs argument
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-18 16:08:12 -05:00
Serge Hallyn
6f259716e7 ubuntu templates: add some kernel filesystems to container fstab
The debugfs, fusectl, and securityfs may not be mounted inside a
non-init userns.  But mountall hangs waiting for them to be
mounted.  So just pre-mount them using $lxcpath/$name/fstab as
bind mounts, which will prevent mountall from trying to mount
them.

If the kernel doesn't provide them, then the bind mount failure
will be ignored, and mountall in the container will proceed
without the mount since it is 'optional'.  But without these
bind mounts, starting a container inside a user namespace
hangs.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-17 09:56:57 -05:00
Dwight Engen
8058be395d clone: only update <rootfs>/etc/hostname if it exists
Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-16 17:25:25 -05:00
John McFarlane
819554fe20
Make get_ips timeout poll configurable
This commit increases the default timeout used by lxc-start-ephemeral
from 5 to 10, and adds support for an LXC_IP_TIMEOUT override.

Patchset 2:
  - Previous patch used a command line arg.

Signed-off-by: John McFarlane <john@rockfloat.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-16 18:10:07 -04:00
Serge Hallyn
5202677243 lxccontainer: don't define certain variables if !HAVE_GNUTLS
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-16 08:16:07 -05:00
Serge Hallyn
27c27d73e1 userns: clear and save id_map (v2)
Otherwise (a) there is a memory leak when using user namespaces and
clearing a config, and (b) saving a container configuration file doesn't
maintain the userns mapping.  For instance, if container c1 has
lxc.id_map configuration entries, then

python3
import lxc
c=lxc.Container("c1")
c.save_config("/tmp/config1")

should show 'lxc.id_map =' entries in /tmp/config1.

Changelog for v2:
   1. fix incorrect saving of group types (s/'c'/'g')
   2. fix typo -> idmap->type should be idmap->idtype

Reported-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Dwight Engen <dwight.engen@oracle.com>
Tested-by: Dwight Engen <dwight.engen@oracle.com>
2013-07-16 08:10:24 -05:00
Serge Hallyn
3ce746862b lxc_create: prepend pretty header to config file (v2)
Define a sha1sum_file() function in utils.c.  Use that in lxcapi_create
to write out the sha1sum of the template being used.  If libgnutls is
not found, then the template sha1sum simply won't be printed into the
container config.

This patch also trivially fixes some cases where SYSERROR is used after
a fclose (masking errno) and missing consts in mkdir_p.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-15 16:34:00 -05:00
Serge Hallyn
868a70afea ubuntu-cloud template: accept --rootfs argument
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-12 15:33:06 -05:00
Serge Hallyn
6a2e602b1b remove old lxc-create script.
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-12 14:08:17 -05:00
Serge Hallyn
dc23c1c817 create: add a quiet flag
If set, then fds 0,1,2 will be redirected while the creation
template is executed.

Note, as Dwight has pointed out, if fd 0 is redirected, then if
templates ask for input there will be a problem.  We could simply
not redirect fd 0, or we could require that templates work without
interaction.  I'm assuming here that we want to do the latter, but
I'm open to changing that.

Reported-by: "S.Çağlar Onur" <caglar@10ur.org>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-12 11:19:54 -05:00
zoolook
ae13ae0853 lxc_clone.c: Allow size subfixes for -L parameter
lxc-clone ignores size subfixes (K, M, G) when using -L parameter. The
following is a quick patch to allow, for example, lxc-clone -L 10G.

Signed-off-by: Norberto Bensa <nbensa@gmail.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-12 10:48:29 -05:00
Serge Hallyn
283678ed2c Accomodate stricter devices cgroup rules
3.10 kernel comes with proper hierarchical enforcement of devices
cgroup.  To keep that code somewhat sane, certain things are not
allowed.  Switching from default-allow to default-deny and vice versa
are not allowed when there are children cgroups.  (This *could* be
simplified in the kernel by checking that all child cgroups are
unpopulated, but that has not yet been done and may be rejected)

The mountcgroup hook causes lxc-start to break with 3.10 kernels, because
you cannot write 'a' to devices.deny once you have a child cgroup.  With
this patch, (a) lxcpath is passed to hooks, (b) the cgroup mount hook sets
the container's devices cgroup, and (c) setup_cgroup() during lxc startup
ignores failures to write to devices subsystem if we are already in a
child of the container's new cgroup.

((a) is not really related to this bug, but is definately needed.
The followup work of making the other hooks use the passed-in lxcpath
is still to be done)

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-11 10:26:33 -05:00
Serge Hallyn
cbee8106e3 lxcapi_create: fix template handling
1. If no template is passed in, then do not try to execute it.  The user
just wanted to write the configuration.

2. If template is passed in as a full path, then use that instead of
constructing '$templatedir/lxc-$template'.

Reported-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-11 10:25:33 -05:00
Serge Hallyn
96b3cb407c lxcapi_create: split out the template execution
Make it its own function to make both more readable.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-11 10:25:10 -05:00
Dwight Engen
fb75356a85 oracle template: use clonehostname hook script
Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-10 14:08:58 -05:00
Dwight Engen
1143ed392d add clonehostname hook
This hook script updates the hostname in various files under /etc in the
cloned container. In order to do so, the old container name is passed in
the LXC_SRC_NAME environment variable.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-10 14:08:43 -05:00
Michael H. Warfield
b9b3a92f66 lxc-fedora template - Fix retries, use os-release for release, add utsname.
Hey all!

Patch for the Fedora template.  Several things...

1) A month or so ago, I floated an idea of adding an option for utsname
which Serge seemed to like but we let it float for more feedback (none
came).

2) In private mail to Serge and Stéphane I mentioned the idea of using
the CPE (Common Platform Enumeration) for host distro and version
identification.  I heard back from Serge but not Stéphane.  CPE is a
standard promoted by NIST and Mitre (along with CVE and CVSS) as part of
the security community as a common identification mechanism.  It's
supported by RedHat based distros and many others (notable exception
Ubuntu).  I've patched the Fedora template to parse first
the /etc/os-release file or, alternatively, the /etc/system-release-cpe
file for the distro ID and version instead of the human
readable /etc/redhat-release.  There's more that can be done with that
in the realm of cross distro container builds, I suspect.

3) At the time of working on 1&2 I noticed that the retry logic in the
Fedora template just didn't seem right.  I believe I posted a message
asking for clarification on that behavior.  A recently post in the
-users list indicating that someone could not create a Fedora 19
container (because the release ver string was 19-2 and the template was
only looking for -1) prompted me to rework the retry logic for handling
the mirror list and servers as well as revamp the download logic to
properly identify the correct release package.

The patch for all of the above is attached below the jump.  It's been
tested on Fedora 17 through Fedora 19 hosts and has created containers
for F11, F12, F13, F14, F16, F17, F18, and F19.  F15 failed for rpm
dependency issues that are not worth fixing (IMHO).

Regards,
Mike
--
Michael H. Warfield (AI4NB) | (770) 985-6132 |  mhw@WittsEnd.com
   /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
   NIC whois: MHW9          | An optimist believes we live in the best of all
 PGP Key: 0x674627FF        | possible worlds.  A pessimist is sure of it!

--

Signed-off-by: Michael H. Warfield <mhw@WittsEnd.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-10 14:07:04 -05:00
Dwight Engen
3327917f4a fix potential out of bounds pointer deref
I noticed that if find_first_wholeword() is called with word at the very
beginning of p, we will deref *(p - 1) to see if it is a word boundary.
Fix by considering p = p0 to be a word boundary.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-10 14:07:03 -05:00
Stéphane Graber
9313e1e628
ubuntu: Tweak layout of the config
Just add an extra white line to both templates.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-09 18:30:52 -04:00
Stéphane Graber
6cda3f5ac1
ubuntu: Fix openssh postinst call in >= saucy
The new openssh uses a different mechanism to start/stop the daemon
which in turn requires a few tweaks in our template to deal with both
the new and old ways of doing that.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
2013-07-08 16:41:08 -04:00
Stéphane Graber
b58e60e232 lxc-start-ephemeral: Fix console() and add storage option
The introduction of the new console() python API broke
lxc-start-ephemeral's console(tty=1) call, I now changed that to
console() which does the right thing with both API versions.

This also adds a new storage-type option, letting the user choose to use
a standard directory instead of tmpfs for the container (but still have
it ephemeral).

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-08 11:50:42 -04:00
Stéphane Graber
39ffde307a python: Update scripts to respect PEP-8 spec
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-08 11:50:42 -04:00
Stéphane Graber
b0f9616f62 python: Re-introduce timeout in get_ips
It turns out that most API users want some kind of timeout option for
get_ips, so instead of re-implementing it in every single client
software, let's just have it as a python overlay upstream.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
2013-07-08 11:50:42 -04:00
Dwight Engen
18efb001a4 fix sshd template
Commit a0a2066d introduced an lxc subdir into the lxc-init path, but
this was never reflected in the sshd template. Add it there.

Don't have ssh-keygen ask for passphrase since host keys are not
supposed to use them.

Don't try to symlink kmsg since /dev is bind mounted readonly.

Read-only bind mount some extra /etc directories, and sysfs which are
needed by dhclient on Fedora and Oracle Linux. Fix mounting of /proc.

Find sshd in more places by adding some common paths to $PATH, and
use the found path to it instead of hardcoded /usr/sbin.

Check for ifconfig command, and print out container's IP address.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-08 09:56:05 -05:00
Bogdan Purcareata
ef091cefca lxcapi_set_cgroup_item: remove duplicate == 0
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-03 12:49:16 -05:00
Dwight Engen
9c631ea7c2 allow lxc-info to get running container configuration
Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-01 16:47:04 -05:00
Dwight Engen
9a15a0f3f8 fix -c argument handling
commit 829dd918 added parsing of a -c argument to both the common options
handling and to lxc-start. It is not a common option, and should have only
been added to lxc-start. Because the common code is processing it, no other
command can use -c. Remove -c from being processed by the common code.
Tested that -c still works with lxc-start.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-01 16:47:03 -05:00
Serge Hallyn
53f3f04845 lxc_conf_init: make sure strdup succeeded
unlikely as a failure may be...

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-07-01 15:32:25 -05:00
Natanael Copa
2e599a6a25 lxc-alpine: make --release work when apk exists
Use sed to set the specified alpine release in the copied
/etc/apk/repositories

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-28 14:38:08 -05:00
Kaarle Ritvanen
982e7b6ea4 lxc-alpine: option for specifying the release to be installed
Signed-off-by: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-27 08:47:39 -05:00
Kaarle Ritvanen
85b41c7d7f lxc-alpine: automatic repository selection
pick random server from mirror list
use the latest stable release

Signed-off-by: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-27 08:47:38 -05:00
Andrew Gilbert
37cb98a2b7 Add -n differentiation to lxc-netstat
lxc-netstat now only processes an -n argument if it has not previously
received a value for $name from --name or -n. If it _has_ received such
a value, it stops processing arguments and leaves the -n for netstat.
This does not apply to the use of --name after a name has been provided
by --name or -n; the current behaviour continues. The new behaviour
makes
	netstat -n <container> -n -a
behave like
	netstat -n <container> -a -n
which already will act as though there is '--' between '<container>' and
'-a' (see line 91 of lxc-netstat.in).

Signed-off-by: Andrew Gilbert <andrewg800@gmail.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-27 08:10:53 -05:00
Andrew Gilbert
1a7cb08504 Add double-dash to lxc-netstat re-call arguments
When lxc-netstat was called by lxc-unshare, it would be given the
arguments intended for netstat from the first invocation, but without
anything to separate them from the arguments intended for lxc-netstat.
This meant that netstat arguments like -n would result in lxc-netstat
trying to process them.

Signed-off-by: Andrew Gilbert <andrewg800@gmail.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-27 08:10:44 -05:00
Serge Hallyn
176d9acb2e api_clone: don't remove storage if we haven't created it
In the best case we'll get errors about failing to remove it.  In the
worst case we'll be trying to delete the original container's rootfs.

Reported-by: zoolook <nbensa+lxcusers@gmail.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-24 13:56:05 -05:00
Serge Hallyn
ae3f8cf9a4 Accept more word delimiters when updating hooks
When updating container names in hook files during a container clone,
we substitute the new container name for the old any time the old name
shows up as a separate word.  This patch adds the four characters
'.,_-' as additional delimiters.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-24 13:56:03 -05:00
Stéphane Graber
618fa49ddd
lxc-start-ephemeral: Fix get_ips call
The timeout option in get_ips has been deprecated, so work around it.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
2013-06-19 14:12:37 -04:00
Serge Hallyn
54c30e2908 conf.c: always strdup rootfs.mount
The reason is that the generic code which handles reading
lxc.rootfs.mount always frees the old value if not NULL.
So without this setting lxc.rootfs.mount = /mnt causes
segfault.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-18 14:52:24 -05:00
Serge Hallyn
37903589a2 don't set up console for lxc-execute
Currently due to some safety checks for !rootfs.path, lxc-execute works
ok if you do not set lxc.rootfs at all in your lxc.conf. But if you
set lxc.rootfs = '/', then it sets up console, and when you do an
lxc-execute, the console appears hung.

However the lxc.rootfs NULL check was just incidental to not dereference
a NULL pointer.  In fact we should not be setting up a console if the
container isn't running a full-fledged distro with a getty/login
running on the container's /dev/console.

Have lxc_execute() mark in lxc_conf that this is a lxc-execute and not
an lxc-start, and don't set up the console.

The issue is documented at https://sourceforge.net/p/lxc/bugs/67/ .

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Dwight Engen <dwight.engen@oracle.com>
2013-06-13 12:03:36 -05:00
Dwight Engen
b515981702 console API improvements
Add a higher level console API that opens a tty/console and runs the
mainloop as well. Rename existing API to console_getfd(). Use these in
the python binding.

Allow attaching a console peer after container bootup, including if the
container was launched with -d. This is made possible by allocation of a
"proxy" pty as the peer when the console is attached to.

Improve handling of SIGWINCH, the pty size will be correctly set at the
beginning of a session and future changes when using the lxc_console() API
will be propagated to it as well.

Refactor some common code between lxc_console.c and console.c. The variable
wait4q (renamed to saw_escape) was static, making the mainloop callback not
safe across threads. This wasn't a problem when the callback was in the
non-threaded lxc-console, but now that it is internal to console.c, we have
to take care of it. This is now contained in a per-tty state structure.

Don't attempt to open /dev/null as the console peer since /dev/null cannot
be added to the mainloop (epoll_ctl() fails with EPERM). This isn't needed
to get the console setup (and the log to work) since the case of not having
a peer at console init time has to be handled to allow for attaching to it
later.

Move signalfd libc wrapper/replacement to utils.h.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-12 15:53:08 -05:00
Natanael Copa
5d4d3ebb13 lxc-init: continue even if we fail to mount /dev/mqueue
The 'lxc-init' (a lightweight init process used by lxc-execute in place
of upstart etc) tries to mount /dev/mqueue during startup. If that fails
(for instance due to missing support for mqueue in kernel) then it
aborts execution and returns -1. This is unreasonable as very few
applications actually need /dev/mqueue.

This similar to what we do with /dev/shm.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-12 08:06:28 -05:00
Serge Hallyn
71b0fed669 lxclock: move container locks into /run/lock
Currently the lxc API mutexes configuration file read/writes with a
lock called $lxcpath/locks/$lxcname.  This fails if the container
is on a rofs.

This patch moves those locks under /run/lock/lxc.

The $lxcpath/$lxcname/partial file is not moved - if you can't
create it, you probably can't create the container either.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-06-11 12:43:25 -05:00
Serge Hallyn
54b79829e2 lxc_stop: return success if api_shutdown succeeded
I originally forgot to set ret = 0 if it succeeded, meaning that a
simple 'lxc-stop -n container1' returns failure even though the
stop succeeded.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-06-10 14:35:03 -05:00
Serge Hallyn
6e46cfcb0e conf.c: if we don't specify a rootfs, we still need proc mounted
otherwise we won't be allowed to set an apparmor context (on pid 1)

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
2013-06-10 10:57:23 -05:00
Qiang Huang
fabf7361da lxc-execute: allow lxc-init to log only when we have a valid log level
Right now if we use lxc-execute without log level set, we get error:
lxc: invalid log priority NOTSET.
Because we set log level manually in execute_start(), but didn't
check if we have a valid log level or not, so fix it.

Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-10 07:20:38 -05:00
Weng Meiling
38973621a4 lxc-ps: display process when container is frozen
When we use lxc-ps to show the process, it's  more appropriate to
show process when container is frozen.

Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-10 07:11:54 -05:00
Rui Xiang
31f58b3fce lxc-monitord: remove hard code execvp path of lxc-monitord
Sometimes, the path of lxc tools is not '/usr/bin', but
'/usr/local/bin' or other. Then execvp lxc-monitord will fail
in lxc_monitord_spawn.

Signed-off-by: Rui Xiang <rui.xiang@huawei.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-10 07:07:29 -05:00
Dwight Engen
f02abefef9 fix check for lock acquired
Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
2013-06-10 06:47:30 -05:00