Commit Graph

82 Commits

Author SHA1 Message Date
John Ferlan
d45bee449c tools: Add support for additional adapter parent options
Add the ability to provide the adapter parent_wwnn and parent_wwpn
or the parent_fabric_wwn on the virsh command line for the pool
define/create as commands.  Update the virsh.pod description.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2018-03-12 09:00:37 -04:00
John Ferlan
8d2247dfd1 tools: Update the help description of the adapter-parent field
One short sentence won't do it justice, but it could help by listing
scsi_hostN and vHBA to point one in the right direction.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2018-03-12 09:00:32 -04:00
Julio Faracco
8fe09a5317 virsh: fixing segfault by pool autocompleter function.
The commands which requires a pool to perform any action for a volume is
throwing a segfault when you pass the volume name before a pool name or
without the argument '--pool'.

An example that works:
virsh # vol-list loops-pool
 Name                 Path
-------------------------------------------------------------------
 loop0                /mnt/loop0

virsh # vol-info --pool loops-pool lo<TAB>

An example that does not work:
virsh # vol-list loops-pool
 Name                 Path
-------------------------------------------------------------------
 loop0                /mnt/loop0

virsh # vol-info lo<TAB>
Segmentation Fault

The example 'vol-info' can be executed as 'vol-info loop0 --pool
loops-pool'. So, this commit fixes this problem when the arguments are
inverted and avoids the segfault.

Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2018-02-28 10:07:35 +01:00
Michal Privoznik
69026fc270 virsh: Introduce virshStoragePoolNameCompleter
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-01-24 13:49:56 +01:00
Michal Privoznik
27b67eba22 virsh: Define multi line macros properly
In some cases there's dangling backward slash at the end of multi
line macros. While technically the code works, it will stop if
some empty lines are removed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-11-04 08:38:08 +01:00
Andrea Bolognani
3e7db8d3e8 Remove backslash alignment attempts
Right-aligning backslashes when defining macros or using complex
commands in Makefiles looks cute, but as soon as any changes is
required to the code you end up with either distractingly broken
alignment or unnecessarily big diffs where most of the changes
are just pushing all backslashes a few characters to one side.

Generated using

  $ git grep -El '[[:blank:]][[:blank:]]\\$' | \
    grep -E '*\.([chx]|am|mk)$$' | \
    while read f; do \
      sed -Ei 's/[[:blank:]]*[[:blank:]]\\$/ \\/g' "$f"; \
    done

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2017-11-03 13:24:12 +01:00
John Ferlan
63d3d895a2 virsh: Add/allow secret-uuid for pool-{define|create}-as
https://bugzilla.redhat.com/show_bug.cgi?id=1476775

For the virsh pool-{define|create}-as command, let's allow using
--secret-uuid on the command line as an alternative to --secret-usage
(added for commit id '8932580'), but ensure that they are mutually
 exclusive.
2017-09-27 08:07:04 -04:00
Julio Faracco
b06521928c storage: Add new events for *PoolBuild() and *PoolDelete().
This commit adds new events for two methods and operations: *PoolBuild() and
*PoolDelete(). Using the event-test and the commands set below we have the
following outputs:

$ sudo ./event-test
Registering event callbacks
myStoragePoolEventCallback EVENT: Storage pool test Defined 0
myStoragePoolEventCallback EVENT: Storage pool test Created 0
myStoragePoolEventCallback EVENT: Storage pool test Started 0
myStoragePoolEventCallback EVENT: Storage pool test Stopped 0
myStoragePoolEventCallback EVENT: Storage pool test Deleted 0
myStoragePoolEventCallback EVENT: Storage pool test Undefined 0

Another terminal:
$ sudo virsh pool-define test.xml
Pool test defined from test.xml

$ sudo virsh pool-build test
Pool test built

$ sudo virsh pool-start test
Pool test started

$ sudo virsh pool-destroy test
Pool test destroyed

$ sudo virsh pool-delete test
Pool test deleted

$ sudo virsh pool-undefine test
Pool test has been undefined

This commits can be a solution for RHBZ #1475227.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1475227

Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-09-20 11:52:56 +02:00
Olga Krishtal
e590d5301e storage: Introduce Virtuozzo vstorage backend
Added general definitions for vstorage pool backend including
the build options to add --with-storage-vstorage checking.
In order to use vstorage as a backend for a storage pool
vstorage tools (vstorage and vstorage-mount) need to be installed.

Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
2017-01-26 10:43:42 -05:00
Chen Hanxiao
b5817855c0 virsh: pool-list: allow both --uuid and --name in one cmd
This patch will allow --uuid and --name in one cmd.
The pool's UUID and name will be printed side by side.

Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
2017-01-18 09:12:31 -05:00
Chen Hanxiao
0d9bcd6ffa virsh: pool-list: introduce --name for printing pool's name only
This patch will introduce option --name.
If specified, only name of pools will be printed out.

Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
2017-01-18 08:46:14 -05:00
Chen Hanxiao
3fe791f8c9 virsh: pool-list: introduce --uuid for printing pool's UUID only
This patch will introduce option --uuid.
If specified, only UUID of pools will be printed out.

Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
2017-01-18 08:46:14 -05:00
Chen Hanxiao
b29f7528ec virsh: pool-info: introduce option --bytes
By default, pool-info will convert sizes to human friendly units.

This patch will introduce option [--bytes].
If specified, the raw sizes will be in the output.

Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
2017-01-10 19:24:41 -05:00
John Ferlan
f23d4bbce3 storage: Fix implementation of no-overwrite for file system backend
https://bugzilla.redhat.com/show_bug.cgi?id=1363586

Commit id '27758859' introduced the "NO_OVERWRITE" flag check for
file system backends; however, the implementation, documentation,
and algorithm was inconsistent. For the "flag" description for the
API the flag was described as "Do not overwrite existing pool";
however, within the storage backend code the flag is described
as "it probes to determine if filesystem already exists on the
target device, renurning an error if exists".

The code itself was implemented using the paradigm to set up the
superblock probe by creating a filter that would cause the code
to only search for the provided format type. If that type wasn't
found, then the algorithm would return success allowing the caller
to format the device. If the format type already existed on the
device, then the code would fail indicating that the a filesystem
of the same type existed on the device.

The result is that if someone had a file system of one type on the
device, it was possible to overwrite it if a different format type
was specified in updated XML effectively trashing whatever was on
the device already.

This patch alters what NO_OVERWRITE does for a file system backend
to be more realistic and consistent with what should be expected when
the caller requests to not overwrite the data on the disk.

Rather than filter results based on the expected format type, the
code will allow success/failure be determined solely on whether the
blkid_do_probe calls finds some known format on the device. This
adjustment also allows removal of the virStoragePoolProbeResult
enum that was under utilized.

If it does find a formatted file system different errors will be
generated indicating a file system of a specific type already exists
or a file system of some other type already exists.

In the original virsh support commit id 'ddcd5674', the description
for '--no-overwrite' within the 'pool-build' command help output
has an ambiguous "of this type" included in the short description.
Compared to the longer description within the "Build a given pool."
section of the virsh.pod file it's more apparent that the meaning
of this flag would cause failure if a probe of the target already
has a filesystem.

So this patch also modifies the short description to just be the
antecedent of the 'overwrite' flag, which matches the API description.
This patch also modifies the grammar in virsh.pod for no-overwrite
as well as reworking the paragraph formats to make it easier to read.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2017-01-10 08:44:50 -05:00
Michal Privoznik
c2a5a4e7ea virstring: Unify string list function names
We have couple of functions that operate over NULL terminated
lits of strings. However, our naming sucks:

virStringJoin
virStringFreeList
virStringFreeListCount
virStringArrayHasString
virStringGetFirstWithPrefix

We can do better:

virStringListJoin
virStringListFree
virStringListFreeCount
virStringListHasString
virStringListGetFirstWithPrefix

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-11-25 13:54:05 +01:00
Erik Skultety
bdd6899b55 tools: Replace vshPrint with vshPrintExtra on places we forgot about
Although there already was an effort (b620bdee) to replace vshPrint occurrences
with vshPrintExtra due to '--quiet' flag, there were still some leftovers. So
this patch fixes them, hopefully for good.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1356881

Signed-off-by: Erik Skultety <eskultet@redhat.com>
2016-11-14 12:14:11 +01:00
Christophe Fergeau
184654117e virsh: Fix *-event error string
When using
virsh net-event non-existing-net
the error message says that 'either --list or event type is required'
This is misleading as 'virsh net-event $valid-event-type' is not going
to work either. What is expected is 'virsh net-event --event
$valid-event-type'

This commit fixes the string in pool-event, nodedev-event, event, and
net-event.
2016-09-08 09:54:12 +02:00
Pino Toscano
4362ff4337 virsh: use vshError consistently after virBufferError checks
If virBufferError() reports an error, then vshError() is needed to
report the error situation instead of a simple vshError().
2016-08-24 17:43:29 +02:00
Pino Toscano
b620bdee14 virsh: respect -q/--quiet more
Turn various vshPrint() informative messages into vshPrintExtra(), so
they are not printed when requesting the quiet mode; neither XML/info
outputs nor the results of commands are affected.
Also change the expected outputs of the virsh-undefine test, since virsh
is invoked in quiet mode there.

Some informative messages might still be converted (and thus silenced
when in quiet mode), but this is an improvements nonetheless.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1358179
2016-08-24 17:43:29 +02:00
Yuri Chornoivan
b277a612c0 Fix unbalanced quotation marks 2016-08-02 12:36:21 +02:00
Daniel Veillard
f9243229fd Revert "Fix unbalanced quotation marks"
This reverts commit 6a40801186.
release of 2.1.0 need to go first
2016-08-02 12:34:18 +02:00
Yuri Chornoivan
6a40801186 Fix unbalanced quotation marks 2016-08-02 09:04:39 +02:00
Daniel P. Berrange
0330848207 Promote storage pool refresh lifecycle event to top level event
The VIR_STORAGE_POOL_EVENT_REFRESHED constant does not
reflect any change in the lifecycle of the storage pool.

It should thus not be part of the storage pool lifecycle
event set, but rather be a top level event in its own
right. Thus we introduce VIR_STORAGE_POOL_EVENT_ID_REFRESH
to replace it.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-06-24 18:26:11 +01:00
Jovanka Gulicoska
eac167e261 virsh: Introduce pool-event command
Similar to 'event' and 'net-event', this prints info about incoming
storage pool events.
2016-06-18 11:15:31 -04:00
John Ferlan
febf69b5e9 virsh: Create macro for common "file" option
Rather than continually cut-n-paste the strings into each command,
create a common macro to be used generically. The macro will take a
single argument _helpstr for the less common help string for each
command option.  Note that only file options using "OT_DATA" and
"OFLAG_REQ" will be replace - others are left as is.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2016-01-11 18:14:00 -05:00
John Ferlan
70c6e67766 virsh: Adjustments for the VIRSH_COMMON_OPT_POOL
The macro is slightly adjusted to add an argument "_helpstr". This
will be passed as a translation macro string since other uses of the
option may not have the same exact help string (such as is the case
when the uuid is not suppliable for create commands).

In virsh-pool.c - we'll create a singular VIRSH_COMMON_OPT_POOL_FULL
in order to pass along the 'N_("pool name or uuid")'

In virsh-volume.c there will be a VIRSH_COMMON_OPT_POOL_FULL and a
VIRSH_COMMON_OPT_POOL_NAME, which passes 'N_("pool name")' for
the commands that can only pass a name. There will also be a
VIRSH_COMMON_OPT_POOL_OPTIONAL which is used for the command
options which use OT_STRING and don't require the --pool argument.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2016-01-11 18:14:00 -05:00
John Ferlan
f688b808ad virsh: Convert VSH_POOL_ macro to VIRSH_COMMON_OPT_
Commit id's 'cf793b00', 'e178688f', 'f9a6110f', '5372d49', and 'e193735'
added new VSH_POOL_ macros; however, it was pointed out after push that
commit id '834c5720' preferred use of VIRSH_ for the prefix over VSH_.

So this patch just changes the VSH_ to VIRSH_ and it changes the naming
format from VIRSH_<opt>_OPT_COMMON to VIRSH_COMMON_OPT_<opt>.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2016-01-11 18:14:00 -05:00
John Ferlan
e193735450 virsh: Add build flags to pool-create[-as] and pool-start
https://bugzilla.redhat.com/show_bug.cgi?id=830056

Utilize recently added VIR_STORAGE_POOL_CREATE_WITH_BUILD* flags in
order to pass the flags along to the virStoragePoolCreateXML and
virStoragePoolCreate API's.

This affects the 'virsh pool-create', 'virsh pool-create-as', and
'virsh pool-start' commands.  While it could be argued that pool-start
doesn't need the flags, they could prove useful for someone trying to
do one command build --overwrite and start command processing or
essentially starting with a clean slate.

NB:
This patch is loosely based upon code originally authored by Osier
Yang that were not reviewed and pushed, see:

https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html
2015-12-17 11:56:18 -05:00
John Ferlan
5372d49b11 virsh: Create a macro for pool-define-as and pool-create-as options
Although they both are the same now, a future patch will add new options
to pool-create-as. So create a common macro to capture commonality, then
use that in the command specific structure.
2015-12-17 11:56:18 -05:00
John Ferlan
f9a6110f26 virsh: Create macro for "overwrite" and no-overwrite" options
Although not currently used in more than one command, it soon will be
so create a common macro to be used in the new command location.

Additionally, add the ".flags = 0," for both to match the expections
of the structure being predefined.
2015-12-17 11:56:18 -05:00
John Ferlan
e178688f8e virsh: Create macro for "file" option
Rather than continually cut/paste the "file" option for pool command
option structures, generate a macro which will commonly define it for
any command.  Then of course use that macro.
2015-12-17 11:56:18 -05:00
John Ferlan
cf793b0042 virsh: Create macro for "pool" option
Rather than continually cut/paste the "pool" option for pool command
option structures, generate a macro which will commonly define it for
any command.  Then of course use that macro.
2015-12-17 11:56:18 -05:00
Erik Skultety
834c5720e4 tools: Introduce new client generic module vsh
In order to share as much virsh' logic as possible with upcomming
virt-admin client we need to split virsh logic into virsh specific and
client generic features.

Since majority of virsh methods should be generic enough to be used by
other clients, it's much easier to rename virsh specific data to virshX
than doing this vice versa. It moved generic virsh commands (including info
and opts structures) to generic module vsh.c.

Besides renaming methods and structures, this patch also involves introduction
of a client specific control structure being referenced as private data in the
original control structure, introduction of a new global vsh Initializer,
which currently doesn't do much, but there is a potential for added
functionality in the future.
Lastly it introduced client hooks which are especially necessary during
client connecting phase.
2015-08-14 15:45:44 +02:00
John Ferlan
cffc099356 virsh: Fix printing of XML for pool-create-as
https://bugzilla.redhat.com/show_bug.cgi?id=1224088

commit id 'bd00e00e' neglected to add the new adapter source options
into the if condition that allowed printing the <source> XML fields.
The <adapter type='fc_host'.../> doesn't require other options in order
to be complete.
2015-06-01 05:40:45 -04:00
Ján Tomko
8995e91b5f Remove unused includes from virsh
After splitting out most of virsh command, some includes
are no longer needed.

Some files have the libXML includes despite not needing them.
2015-04-02 10:27:56 +02:00
Pavel Hrdina
03369d9643 pool-define: update and unify documentation
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1127045

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
2015-03-09 14:47:53 +01:00
Hao Liu
a0670aef37 virsh: Emit error for VSH_OT_DATA without VSH_OFLAG_REQ
Commit 6b9964 enforces checking invalid use of VSH_OT_STRING with
VSH_OFLAG_REQ. This commit tries to do the same thing to stop using
VSH_OT_DATA without VSH_OFLAG_REQ and also fix existing misuse.

Signed-off-by: Hao Liu <hliu@redhat.com>
2015-01-12 13:38:42 +01:00
John Ferlan
bd00e00eaf virsh: Add adapter options for pool-{create|define}-as
Add the optional adapter options for pool create/define.  Results in
either:

<adapter type='scsi_host' name='scsi_host2'/>

or (on one line)

<adapter type='fc_host' parent='scsi_host5'
         wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/>

being generated.
2014-12-05 11:49:53 -05:00
John Ferlan
893258063d virsh: Add auth options for pool-{create|define}-as
Add 3 new optional options for the pool-create-as and pool-define-as
command in order to define the 3 elements required in order to add
an auth element, such as:

<auth type='chap' username='myuser'>
  <secret usage='libvirtiscsi'/>
</auth>
2014-12-05 11:49:52 -05:00
Martin Kletzander
91cc3d9570 Remove unnecessary curly brackets in tools/
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2014-11-14 17:13:36 +01:00
Martin Kletzander
e09f9e4c32 virsh: Convert EDIT_NOT_CHANGED macro to do-while block.
This macro is being used as an inline body after an if and might get
pretty confusing.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2014-11-14 17:13:00 +01:00
Martin Kletzander
11d9dd1ad8 virsh: Reorder some options
According to comments in parsing functions, optional options should be
specified *after* required ones.  It makes sense and help output looks
cleaner.  The only exceptions are options with type == VSH_OT_ARGV.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2014-11-13 15:44:23 +01:00
John Ferlan
daf27d4d82 virsh: Resolve Coverity DEADCODE
Since 0766783abb

Coverity complains that the EDIT_FREE definition results in DEADCODE.

As it turns out with the change to use the EDIT_FREE macro the call to
vir*Free() wouldn't be necessary nor would it happen...

Prior code to above commitid would :

  vir*Ptr foo = NULL;
  ...
  foo = vir*GetXMLDesc()
  ...
  vir*Free(foo);
  foo = vir*DefineXML()
  ...

And thus the free was needed.  With the change to use EDIT_FREE the
same code changed to:

  vir*Ptr foo = NULL;
  vir*Ptr foo_edited = NULL;
  ...
  foo = vir*GetXMLDesc()
  ...
  if (foo_edited)
      vir*Free(foo_edited);
  foo_edited = vir*DefineXML()
  ...

However, foo_edited could never be set in the code path - even with
all the goto's since the only way for it to be set is if vir*DefineXML()
succeeds in which case the code to allow a retry (and thus all the goto's)
never leaves foo_edited set

All error paths lead to "cleanup:" which causes both foo and foo_edited
to call the respective vir*Free() routines if set.

Signed-off-by: John Ferlan <jferlan@redhat.com>
2014-09-11 08:03:37 -04:00
Roman Bogorodskiy
0257d06ba4 storage: ZFS support
Implement ZFS storage backend driver. Currently supported
only on FreeBSD because of ZFS limitations on Linux.

Features supported:

 - pool-start, pool-stop
 - pool-info
 - vol-list
 - vol-create / vol-delete

Pool definition looks like that:

 <pool type='zfs'>
  <name>myzfspool</name>
  <source>
    <name>actualpoolname</name>
  </source>
 </pool>

The 'actualpoolname' value is a name of the pool on the system,
such as shown by 'zpool list' command. Target makes no sense
here because volumes path is always /dev/zvol/$poolname/$volname.

User has to create a pool on his own, this driver doesn't
support pool creation currently.

A volume could be used with Qemu by adding an entry like this:

    <disk type='volume' device='disk'>
      <driver name='qemu' type='raw'/>
      <source pool='myzfspool' volume='vol5'/>
      <target dev='hdc' bus='ide'/>
    </disk>
2014-08-12 19:40:20 +04:00
Julio Faracco
1ce86e62e1 conf: use typedefs for enums in "src/conf/storage_conf.h"
In "src/conf/" there are many enumeration (enum) declarations.
Similar to the recent cleanup to "src/util" directory, it's
better to use a typedef for variable types, function types and
other usages. Other enumeration and folders will be changed to
typedef's in the future. Most of the files changed in this
commit are related to storage (storage_conf) enums.

Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-05-14 10:18:35 -06:00
Ján Tomko
5d8793eebb Indent top-level labels by one space in tools/ 2014-03-25 14:58:41 +01:00
Martin Kletzander
cc9c62fef9 Require spaces around equality comparisons
Commit a1cbe4b5 added a check for spaces around assignments and this
patch extends it to checks for spaces around '=='.  One exception is
virAssertCmpInt where comma after '==' is acceptable (since it is a
macro and '==' is its argument).

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2014-03-18 11:29:44 +01:00
Laine Stump
64bb902451 virsh: eliminate hardcoded indentation in xml generated for commands
These are never seen externally, only passed into libvirt APIs, so in
practice this makes no real difference, but it's good to be
consistent.
2014-03-14 00:02:38 -06:00
Eric Blake
50f7960d37 virsh: kill over-engineered asprintf failure recovery
I noticed this while shortening switch statements via VIR_ENUM.
Basically, the only ways virAsprintf can fail are if we pass a
bogus format string (but we're not THAT bad) or if we run out
of memory (but it already warns on our behalf in that case).
Throw away the cruft that tries too hard to diagnose a printf
failure.

* tools/virsh-volume.c (cmdVolList): Simplify.
* tools/virsh-pool.c (cmdPoolList): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-24 11:47:18 -07:00
Eric Blake
466b12ab79 virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future.  Make this change throughout virsh.

Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.

* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.

Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-24 11:47:18 -07:00