an empty schedule means 'none', so do not fill it with the default
in case we edit an existing job (like we do already for sync jobs)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
findRecord does not match exactly, but only at the beginning and
case insensitive, by default. Change all calls to be case sensitive
and an exactmatch (we never want the default behaviour afaics).
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
used in the PBS GUI, but also for PVE usage queries which don't need all
the extra expensive information..
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
avoids that it shows during store load, we do not know if there are
no datastores at that point and have already a loading mask.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
when we could not load the config (e.g. missing permissions)
show the comment from the global datastore-list
also show a messagebox for a load error instead of setting
the text of the comment box
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
the .lint-incremental target, which is implicitly used by the install
target, is still more forgiving to allow faster "change, build, test"
iteration when developing.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Without hyphens, we had 20 hex digits, so ~80 bit which is probably overkill.
Use 12 (13 with hyphen), this is still 48 bit.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
add missing help buttons (question mark, top right) so that we are
consistent and each panel has it.
I chose the IMHO most fitting sections.
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
its rather hacky, but our cbind mixin does not support columns (yet).
if it does sometime in the future, we could use that instead
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
added a few more help buttons were appropriate:
* GC and Prune schedule windows
* Create Directory window
* API Tokens, link directly to token section
* verify jobs window
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
changes the layout to look i little bit more like the statistics panel
we have for ceph in pve, while changing to the UsageChart and adding
some more datastore infos (from last garbage collect)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
heavily inspired by pveRunningChart, without the dynamically adding
of data and specific for the usage of datastores
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Fix font-size to 14px to improve font-awesome rendering, add some
slight margin between the buttons so that they are not glued
together, add a slight text-shadow on mouse over.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
a panel for a single datastore that gets updated from an external caller
shows the usage, estimated full date, history and task summary grid
a panel that dynamically generates the panel above for each datastore
and a tabpanel that includes the panel above, as well as a global
syncview, verifiyview and aclview
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this makes it a little easier to provide good data, without
hardcoding all types in the source object
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
it seems that under certain circumstances, extjs does not initialize
or remove the content from objects in controllers
move it to the view, were they always exist
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
we want to use this panel again for a 'global' overview, without
any datastore preselected, so we have to handle that, and
adding a datastore selector in the editwindow
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
to parse the datastore out of a worker_id
for this we need some regexes that are the same as in the backend
for now we only parse out the datastore, but we can extend this
in the future to parse relevant info (e.g. remote for syncs,
id/type for backups)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
since just the ACLs defined on the exact datastore path don't give
anywhere near a complete picture of who has access to it.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
with the "change owner" action added we now need more than the
default of 100 px, so increase to 120 px for now.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
slightly adapted, i.e., the delete_if_default helper always sets the
delete property to an array if not existing.
Also, filtering out undefined values when printing properties.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Extension of fix#2847
Adds an action button to the datastore content view,
to change the owner of a backup.
Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
Includes some eslint fixes and label changes as well, was to much
work to split that out in its own commit.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
this is a panel that is heavily inspired from widget-toolkits
node/Tasks panel, but is adapted to use the extended api calls of
pbs (e.g. since/until filter)
has 'filter' panel (like pmgs log tracker gui), but it is collapsible
if we extend the api calls of the other projects, we can merge this
again into the widget-toolkit one and use that
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
and change all users of the /status/tasks api call to this
with this change we can now delete the /status/tasks api call
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
instead of hard-coding 'backup@pam'. this allows a bit more flexibility
(e.g., syncing to a datastore that can directly be used as restore
source) without overly complicating things.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Avoid overuse of flex, that is as bad as having all to fixed widths.
In spirit similar to the previous commit for the verify panel, see
that for some rationale.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Avoid overuse of flex, that is as bad as having all to fixed widths.
* Set date-time fields to 150 px as they are fixed width text.
* Duration is maximal 3 units, so it can be made fixed too.
* Schedule is flex with lower and upper limits, this is useful as
it's a field which can be both, quite short (daily) or long
(mon..fri *-10..12-1..7 02:00/30:30)
* Status and comment is flex, this way we always get a filled grid
Move status after last verify date and duration field, increases
information density at the left of the grid - reducing need for eye
movement, also, it groups together the "information about last job"
nicer.
Show job-id by default even if they are auto generated when adding
over the gui, as it can help finding the respective job faster when
getting a mail with an error.
Reported-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
orient on PVE, the ones for Updates, ServerStatus, should by
self-explanatory.
Services is in PVE named "System", but reusing that cogs icon makes
similar sense here too, and seems in line with search result of a
"service icons" query.
Syslog is the same as our general log icon, but as we also use this
normally for worker task logs and that is present here too, I
changed the worker task log icon to the alternative list, which
resembles a task view window - so IMO even better than before.
Sync that change also into the always present tasks button at the top
right.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
in most generic places. this is accompanied by a change in
RpcEnvironment to purposefully break existing call sites.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
the config is shared between multiple datastores with the ID as, well
the unique ID, but we only show those of a single datastore.
So if a user adds a new one with a fixed ID "12345" but a job with
that ID exists already on another store, they get a error about
duplicate IDs, but cannot relate as that duplicate job is not visible
(filtered away)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
by moving the properties of the storage status out again to the top
level object
also introduce proper structs for the types used, to get type-safety
and better documentation for the api calls
this changes the backup counts from an array of [groups,snapshots] to
an object/struct with { groups, snapshots } and include 'other' types
(though we do not have any at this moment)
this way it is better documented
this also adapts the ui code to cope with the api changes
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
the "comment" is the first line of the "notes" field from a manifest,
show it in the grid and allow editing the full notes.
Hack the click event listener a bit together for the right aligned
edit action button, but it works out well and is efficient (only one
event listener is much cheaper than per-buttons ones).
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Choosing a good icon is hard here, while the magnifying glass is
somewhat relatable, it reminds to much of a "Search" function, which
can be quite confusing here.
So use a simple "V.", even if it's probably also not to ideal..
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
so that the last selected tab for datastores will get selected
the next time any datastore is selected, even across browser
reloads
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this fixes some bugs related to selection handling in the treelist:
* datastores were not selected after a reload
* reloading when in a tabpanel on any tab but the first, would
not select a treenode
* changing between datastores on any tab but the first would
not select the same tab on the new datastore
fixed those by mostly rewriting the changePath handling for
datastores and tabpanels in general
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
and make 'Datastore' unclickable
since we have all options and information on the relevant datastore panels,
we do not need a datastore config anymore (besides the creation,
which we add here)
this also fixes the sorted insertion and removal of new/old datastores
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
add the datastore as parameter for the store, remove
the datastore selector for the edit windows and give the datastore
to it instead
also remove the autostart from the rstore, since we only want to start
it when we change to the relevant tab
and add icons for all other datastore tabs
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this adds a 'Summary' panel to the datastores, similar to what we have
for PVE's nodes/guests/storages
contains an info panel with useful information, a comment field, and
the charts from the statistics panel (which can be deleted since it is
not necessary any more)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
a simple objectgrid to display datastore gc/prune options
needs the prune inputpanel to be refactored in its own class
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
by using the new ZipEncoder and recursively add files to it
the zip only contains directories, normal files and hardlinks (by simply
copying the content), no symlinks, etc.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
for now this isn't needed and would take quite a bit of effort to
match the API schema with PVE.
if there are a lot of requests at some point we can add it in.
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
when clicking on a count in the summary, a small task overlay now pops
up that shows those tasks. this way, the user has an easy way
of seeing which tasks failed exactly
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
by moving the definition into the controller and dynamically use them
in the updateTasks function
we will reuse/extend this later
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
we showed 'last month' even if we did not limit the api call
implement that and make the number of days configurable
(we have most of the code already available for that, since
the base dashboard got copied from pmg and never cleaned up)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
while restructuring the docs, explicit title wasn't included in the
correct file
fixes commit 04e24b14f0
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
use our hostport regexes to parse out a potential port from the host field
and send it individually
this makes for a simpler and cleaner ui
this additionally checks the field for valid input before sending it to
the backend
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
* add square brackets to ipv6 adresses in BackupRepository if they not
already have some (we save them without in the remote config)
* in get_pull_parameters, we now create a BackupRepository first and use
those values (which does the [] mapping), this also has the advantage
that we have one place less were we hardcode 8007 as port
* in the ui, add square brackets for ipv6 adresses for remotes
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
by setting a maxHeight+scrollable
(i used 500px to be still visible on our 'min screen size' 1280x720)
and by disabling emptyText deferral, which now shows the text instantly
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
name sections according to the title or content and add
the respective onlineHelp to the following panels:
- datastore
- user management
- ACL
- backup remote
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
Reviewed-By: Dominik Csapak <d.csapak@proxmox.com>
Tested-By: Dominik Csapak <d.csapak@proxmox.com>
*/x is valid syntax for us, but not systemd, so to not confuse users
write it like systemd would accept it
also an timespec must at least have hours and minutes
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
if we have a stale backup without an manifest, we do not count
the remaining files in the backup dir anymore, but this means
we now have to check here if there are really any encrypted
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
goes through the sections in the documents and creates the
OnlineHelpInfo.js file from the explicitly defined section labels which
are used in the js files with 'onlineHelp' variable.
Allows to differ the following situations:
* some snapshots in a group where not verified
* how many snapshots failed to verify in a group
* all snapshots verified but last verification task was over 30 days
ago
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Using 75 as width we can display up to 9999999 which would allow
displaying over 19 years of snapshots done each minute, so quite
enough for the common cases.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
do not count files where we do not have any information
such files exist in the backup dir, but are not in the manifest
so we cannot use those files for determining if the backups are
encrypted or not
this marks encrypted/signed backups with unencrypted client.log.blob files as
encrypted/signed (respectively) instead of 'Mixed'
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Double-click on the verify grid-cell of a specific snapshot (not the
group) opens the relevant task log.
The date of the last verify is shown as tool-tip.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
to also have the correct icons for warnings and unknown tasks
the text is here "ERROR: ..." now, so leave the 'Error' out
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
just because we can't verify the signature, does not mean the contents
are not accessible. it might make sense to make it obvious with a hint
or click-through warning that no signature verification can take place
or this and downloading.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
...when an entry is selected, that doesn't exist after the reload.
E.g. when one deletes selects a file within a snapshot and then clicks
the delete icon for said snapshot, focusRow would then fail and the
loading mask stay on until a reload.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
when clicking reload, we keep the existing selection
(if it still exists), and the previous expanded elements expanded
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
which searches the whole tree (name & owner)
we do this by traversing the tree and marking elements as matches,
then afterwards make a simple filter that matches on a boolean
worst case cost of this is O(2n) since we have to traverse the
tree (in the worst) case one time, and the filter function does it again
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
instead of having the files as a column, put the files into the tree
as a third level
with this, we can move the actions into an action column and remove
the top buttons (except reload)
clicking the download action now downloads directly, so we would
not need the download window anymore
clicking the browse action, opens the pxar browser like before,
but expands and selects (&focus) the selected pxar file
also changes the icon of 'signed' to the one to locked
but color codes them (singed => greyed out, encrypted => green),
similar to what browsers do/did for certificates
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
taken mostly from PVE, with adaption to how PBS does things.
Main difference is that we do not have a resource store singleton
here which we can use, but for datastores we can already use the
always present datastore-list store. Register it to the store manager
with a "storeId" property (vs. our internal storeid one).
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
modelled after the PVE one, but we are not 1:1 compatible and need
deleteEmpty support. For now let's just have some duplicate code, but
we should try to move this to widget toolkit ASAP.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This aligns it with PVE and allows the widget toolkit's update window
"refresh" to work without modifications once POST /apt/update is
implemented.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
Two digits fit nicely, and the extra plus for the >99 case doesn't
takes that much space either. So that and the fact that 9 is just
really low makes me bump this to 99 as cut-off value.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
the idea is to blend in when no task is running, thus no
background-color there. When tasks are running use the proxmox
branding guideline dark-grey, it isn't used as often so it should
fall into ones eye when changing but it has some use so it doesn't
seems out of place.
Reduce the border radius by a lot, so that it seems similar to the
one our ExtJS theme uses for the buttons outside - the original
border radius seems like it comes from the time where this was
intended to be a floating badge, there it'd make sense but as
integrated button one this seems to fit the style much more.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
we can now show 'none', 'encprypted', 'signed' or 'mixed' for
the crypt mode
also adds a different icon for signed files, and adds a hint that
signatures cannot be verified on the server
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
We cannot verify, download, file-browse backups which are currently
in progress.
'Forget' could work but is probably not desirable?
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
if the baseCls is not 'x-plain' the background of the flex
element is white, and on some zoom steps it gets taller
than one pixel and appears as a white line
making it have the plain baseCls, so it does not get any
background color and is always invisible
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
the api call can take a very long time (for now), until we can
improve that, increase the timeout from the default of 30s
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Not even hard feeling on 'Datastore' vs. 'Data Store' but consistency
is desired in such names.
Talked shortly with Dominik, which also slightly favored the one
without space - so just go for that one.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
it is only designed to be a quick overview, so having holes there
is not really pretty and since we do not even show any date
for the points, we can simply reuse the last value for holes
the 'real' graph with holes is still available on the
DataStoreStatistics panel
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this will make refactoring easier for panels that are reused from pve
(where we always have a hostname)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
we have to use the correct store, and we have to manually show the
error (since monStoreErrors only works for Proxmox Proxies)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Get the first visible node through the Ext.data.NodeInterface defined
"firstChild" element and expand that if there's only one archive
present.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
enables to be able to download whole files from the backup (e.g.
the decoded didx/fidx/blobs) for unencrypted backups
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
do not use two different gettexts for groups and single backups
and correct logic for backup groups
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this also contains an adapted CreateDirectory window
for now this is mostly copied, since refactoring was not that
straightforward (changed parameters, etc.)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
by querying the new /status/task api every 15 seconds
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
[w.bumiller@proxmox.com: fixup from d.csapak@proxmox.com]
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
LongestTasks:
grid that shows tasks sorted by duration in descending order
RunningTasks:
grid that shows all running tasks
TaskSummary:
an overview of backup,prune,gc and sync tasks (error/warning/ok)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
with these changes fa icons in actioncolumns,
they have the same layout as <i> elements on the same line
(they were slightly bigger and offset before)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
shows an overview over the datastores, including a small chart of the
past month and an estimation of when its full
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
by adding them as columns for the config view,
and as a seperate tab on the edit window (this is done to not show
too many options at once)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
split them into two files and put them into the respective directory
refactor the DataStoreConfigPanel to controller/view
and the DataStoreEdit window/inputpanel to simply an editwindow
(there is no need to have a seperate inputpanel) which also
prepares the window for edit (by using pmxDisplayEditFields)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
We will show an overall status of the DataStores in the Dashboard, so there
is no need for a seperate DataStores Status.
This means we can move the Config to where the Status was, and remove
the duplicated entry in the NavigationTree, reducing confusion for users
We can still seperate the permissions by simply showing a permission
denied error, or simply leaving the list empty
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
the remove button did not get the selModel since the xytpe was not
'grid' so give it the correct xtype
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
if the last sync job is too far in the past (or there was none at all
for now) we run it at the next iteration, so we want to show that
we now calculate the next_run by using either the real last endtime
as time or 0
then in the frontend, we check if the next_run is < now and show 'pending'
(we do it this way also for replication on pve)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this uses different parameters which we want to be the same for
all products (e.g. secure cookie)
leave the PBS.Utils.updateLoginData for the case that we want to do
something more here (as in pve for example)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
while touching it, make columns and tbar in DataStoreContent.js
declarative members and remove the (now) unnecessary initComponent
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
shows a nice overview of sync jobs (incl status of last run, estimated
next run, etc.) with options to add/edit/remove and also show the
log of the last run and manually run it now
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
'sync' is used for manually pulling a remote datastore
changing it for a scheduled sync to 'syncjob' so that we can
differentiate between both types of syncs
this also adds a seperate task description for it
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
when using a diffstore, we have to add all used columns to the model,
else they will not refresh on a load
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Avoid triggering non-required background updates during browsing a
datastores content or statistics panels. They're not expensive, but I
do not like such behavior at all (having traveled with trains and
spotty network to often)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Mostly refactoring, but actually fixes an issue where one seldom run
into a undefined dereference due to the store onLoad callback getting
triggered after some of the componet was destroyed - on quick
switching through the datastores.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
adding a new one after load will append it still at the end, though.
But datastores are not something which get frequently added after
initial setup, so don't care about that for now..
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
by introducing a datastorepanel (a TabPanel) which holds the content
and acl panel for now.
to be able to handle this in the router, we have to change the logic
of how to select the datastore from using the subpath to putting it
into the path (and extracting it when necessary)
if we need this again (e.g. possibly for remotes), we can further
refactor this logic to be more generic
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
this has to be different from pve for now, since the default of
'enabled' is reverted (pve: default disabled, pbs: default enabled)
if we decide to change this either here or in pve, we can refactor
it to the widget-toolkit
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
using a handlebars instance in ApiConfig, to cache the templates
as long as possible, this is currently ok, as the index template
can only change when the whole package changes
if we split this in the future, we have to trigger a reload of
the daemon on gui package upgrade (so that the template gets reloaded)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>