[Kimchi-devel] [PATCH] Making urls relative

Frederic Bonnard frediz at linux.vnet.ibm.com
Tue Mar 10 14:59:08 UTC 2015


Hi Aline,
sorry, after you replied with another mail with "make check" I thought you
changed your idea on this point.
Actually, nginx shouldn't be started by Kimchi, that was not my point or
I missed something :)

The point is to make kimchi be url-location agnostic if possible.
That is, you can do rewriting with nginx and put make kimchi whereever you
want.
The problem now, is quite often, the following :
the javascript kimchi client api asks for /host/stats (for instance).
nginx forwards the request to kimchi server.
If all is placed at root, that works :
--- at the moment ---
client: GET kimchi_server /index.html
nginx: forwards /index.html to local kimchi
kimchi: checks for /index.html and replies
nginx: forwards to client
client: nice, lets continue browsing the page: we need /host/stats in index.html
client: GET kimchi_server /host/stats
nginx: forwards /host/stats to local kimchi
kimchi: checks for /host/stats and replies
---

If you want to change kimchi location as distros will want to, by having it in
a sub location (virtualhosting won't be a problem except if kimchi expects
a specific hostname), kimchi will fail because it expects a specific path :

--- distro doing rewriting in nginx to serve http://kimchi_server/path/to/kimchi/
client: GET kimchi_server /path/to/kimchi/index.html
nginx: rewrites URL to /index.html and forward to local kimchi
kimchi: checks for /index.html and replies
nginx: forwards to client
client: nice, lets continue browsing the page: we need /host/stats in index.html
client: GET kimchi_server /host/stats
nginx: no rewrite to do as not matching any /path/to/kimchi/ so checking /host/stats
       on the web server and fails as there's no source for it -> 404
---

Here, index.html shouldn't have mention /host/stats but host/stats so that request
wouldn't have been /host/stats but /path/to/kimchi/host/stats (relative to
original page) and then nginx could have rewrite the URL to /host/stats and
forwarded it to kimchi.
So the main work is to have in the templates, the good relative URLs and the
same in the javascript.
Few changes in the core kimchi daemon.
Hope I explained clearly, and if I didn't get your point, let me know (btw, I'm
on bluenet IRC, #4321 as frediz)

F.


On Fri, 27 Feb 2015 13:50:00 -0300, Aline Manera <alinefm at linux.vnet.ibm.com> wrote:
> 
> Maybe it would be good to make Kimchi smarter to automatically connect 
> to the external web server.
> For example, we could add a new parameter in Kimchi config file 
> (/etc/kimchi/kimchi.conf) and once it is filled up we start the nginx 
> proxy according to it. Otherwise, we keep starting Kimchi on 
> http://server:8000/
> What do you think?
> 
> On 26/02/2015 10:25, Frédéric Bonnard wrote:
> > From: Frederic Bonnard <frediz at linux.vnet.ibm.com>
> >
> > The goal is to be able to have kimchi website elsewhere than / , for example
> > https://server/kimchi/
> > Also providing an nginx configuration file example that can serve kimchi at the
> > URL above.
> > ---
> >   docs/Makefile.am                      |   1 +
> >   docs/nginx.conf.subsite.ex            |  37 +++++++
> >   src/kimchi/screenshot.py              |   2 +-
> >   ui/css/theme-default/template_add.css |  20 ++--
> >   ui/css/theme-default/topbar.css       |   2 +-
> >   ui/js/src/kimchi.api.js               | 176 +++++++++++++++++-----------------
> >   ui/js/src/kimchi.login.js             |   2 +-
> >   ui/pages/guest.html.tmpl              |   2 +-
> >   ui/pages/help/dita-help.xsl           |   4 +-
> >   ui/pages/kimchi-ui.html.tmpl          |   4 +-
> >   ui/pages/storagepool-add.html.tmpl    |   2 +-
> >   ui/pages/tabs/storage.html.tmpl       |   2 +-
> >   ui/pages/template-add.html.tmpl       |   2 +-
> >   13 files changed, 147 insertions(+), 109 deletions(-)
> >   create mode 100644 docs/nginx.conf.subsite.ex
> >
> > diff --git a/docs/Makefile.am b/docs/Makefile.am
> > index 679aa18..a73d4c5 100644
> > --- a/docs/Makefile.am
> > +++ b/docs/Makefile.am
> > @@ -25,4 +25,5 @@ dist_doc_DATA = \
> >   	README-federation.md \
> >   	kimchi-guest.png \
> >   	kimchi-templates.png \
> > +	nginx.conf.subsite.ex \
> >   	$(NULL)
> > diff --git a/docs/nginx.conf.subsite.ex b/docs/nginx.conf.subsite.ex
> > new file mode 100644
> > index 0000000..5b2b3bc
> > --- /dev/null
> > +++ b/docs/nginx.conf.subsite.ex
> > @@ -0,0 +1,37 @@
> > +server {
> > +    sendfile    on;
> > +
> > +    client_max_body_size 4194304k;
> > +
> > +    # Timeout set to 10 minutes to avoid the 504 Gateway Timeout
> > +    # when Kimchi is processing a request.
> > +    proxy_connect_timeout       600;
> > +    proxy_send_timeout          600;
> > +    proxy_read_timeout          600;
> > +    send_timeout                600;
> > +
> > +        error_log /var/log/nginx/test.log debug;
> > +        rewrite_log on;
> > +        listen 443 ssl;
> > +
> > +        ssl_certificate /etc/kimchi/kimchi-cert.pem;
> > +        ssl_certificate_key /etc/kimchi/kimchi-key.pem;
> > +
> > +        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
> > +        add_header X-Frame-Options DENY;
> > +        add_header X-Content-Type-Options nosniff;
> > +        add_header X-XSS-Protection "1; mode=block";
> > +
> > +        location /kimchi/ {
> > +            proxy_pass http://127.0.0.1:8010/;
> > +            proxy_set_header Host $host;
> > +            proxy_set_header X-Real-IP $remote_addr;
> > +            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> > +            proxy_redirect http://127.0.0.1:8010/ https://$host/kimchi/;
> > +        }
> > +}
> > +
> > +server {
> > +   listen 80;
> > +   rewrite ^/kimchi/(.*)$ https://$host/kimchi/$1 redirect;
> > +}
> > diff --git a/src/kimchi/screenshot.py b/src/kimchi/screenshot.py
> > index e599d40..fc9aaac 100644
> > --- a/src/kimchi/screenshot.py
> > +++ b/src/kimchi/screenshot.py
> > @@ -68,7 +68,7 @@ class VMScreenshot(object):
> >           if now - last_update > self.OUTDATED_SECS:
> >               self._clean_extra(self.LIVE_WINDOW)
> >               self._generate_thumbnail()
> > -        return '/data/screenshots/%s' %\
> > +        return 'data/screenshots/%s' %\
> >                  os.path.basename(self.info['thumbnail'])
> >
> >       def _clean_extra(self, window=-1):
> > diff --git a/ui/css/theme-default/template_add.css b/ui/css/theme-default/template_add.css
> > index e58bccb..f005a2c 100644
> > --- a/ui/css/theme-default/template_add.css
> > +++ b/ui/css/theme-default/template_add.css
> > @@ -41,7 +41,7 @@
> >       float: left; display : block;
> >       width: 50px;
> >       height: 52px;
> > -    background: url(../../images/theme-default/icon-back.png) center
> > +    background: url(../images/theme-default/icon-back.png) center
> >                   center no-repeat;
> >       cursor: pointer;
> >       display: block;
> > @@ -59,17 +59,17 @@
> >       margin: 0 10px 10px;
> >       padding: 20px 10px 20px 65px;
> >       border: 2px solid #ccc;
> > -    background: url(../../images/theme-default/icon-local.png) 15px
> > +    background: url(../images/theme-default/icon-local.png) 15px
> >                   center no-repeat;
> >       cursor: pointer;
> >   }
> >
> >   .step-choose>li>a.local {
> > -    background-image: url(../../images/theme-default/icon-local.png);
> > +    background-image: url(../images/theme-default/icon-local.png);
> >   }
> >
> >   .step-choose>li>a.remote {
> > -    background-image: url(../../images/theme-default/icon-remote.png);
> > +    background-image: url(../images/theme-default/icon-remote.png);
> >   }
> >
> >   .step-choose>li>a:HOVER {
> > @@ -176,27 +176,27 @@
> >   }
> >
> >   .iso-icon.centos {
> > -    background-image: url(../../images/icon-centos.png);
> > +    background-image: url(../images/icon-centos.png);
> >   }
> >
> >   .iso-icon.debian {
> > -    background-image: url(../../images/icon-debian.png);
> > +    background-image: url(../images/icon-debian.png);
> >   }
> >
> >   .iso-icon.fedora {
> > -    background-image: url(../../images/icon-fedora.png);
> > +    background-image: url(../images/icon-fedora.png);
> >   }
> >
> >   .iso-icon.opensuse {
> > -    background-image: url(../../images/icon-opensuse.png);
> > +    background-image: url(../images/icon-opensuse.png);
> >   }
> >
> >   .iso-icon.ubuntu {
> > -    background-image: url(../../images/icon-ubuntu.png);
> > +    background-image: url(../images/icon-ubuntu.png);
> >   }
> >
> >   .iso-icon.gentoo {
> > -    background-image: url(../../images/icon-gentoo.png);
> > +    background-image: url(../images/icon-gentoo.png);
> >   }
> >
> >   .list-iso {
> > diff --git a/ui/css/theme-default/topbar.css b/ui/css/theme-default/topbar.css
> > index d21fc50..04676b8 100644
> > --- a/ui/css/theme-default/topbar.css
> > +++ b/ui/css/theme-default/topbar.css
> > @@ -132,7 +132,7 @@
> >   }
> >
> >   #user-icon {
> > -    background: url("/images/theme-default/user-icon.png") no-repeat left top;
> > +    background: url("../images/theme-default/user-icon.png") no-repeat left top;
> >       height: 16px;
> >       width: 16px;
> >   }
> > diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> > index 2abe8f5..277bf55 100644
> > --- a/ui/js/src/kimchi.api.js
> > +++ b/ui/js/src/kimchi.api.js
> > @@ -54,7 +54,7 @@ var kimchi = {
> >       getCapabilities : function(suc, err, done) {
> >           done = typeof done !== 'undefined' ? done: function(){};
> >           kimchi.requestJSON({
> > -            url : "/config/capabilities",
> > +            url : "config/capabilities",
> >               type : "GET",
> >               contentType : "application/json",
> >               dataType : "json",
> > @@ -69,7 +69,7 @@ var kimchi = {
> >        */
> >       getI18n: function(suc, err, url, sync) {
> >           kimchi.requestJSON({
> > -            url : url ? url : kimchi.url + 'i18n.json',
> > +            url : url ? url : 'i18n.json',
> >               type : 'GET',
> >               resend: true,
> >               dataType : 'json',
> > @@ -84,7 +84,7 @@ var kimchi = {
> >        */
> >       getHost: function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host',
> > +            url : 'host',
> >               type : 'GET',
> >               resend: true,
> >               contentType : 'application/json',
> > @@ -99,7 +99,7 @@ var kimchi = {
> >        */
> >       getHostStats : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/stats',
> > +            url : 'host/stats',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               headers: {'Kimchi-Robot': 'kimchi-robot'},
> > @@ -114,7 +114,7 @@ var kimchi = {
> >        */
> >       getHostStatsHistory : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/stats/history',
> > +            url : 'host/stats/history',
> >               type : 'GET',
> >               resend: true,
> >               contentType : 'application/json',
> > @@ -138,7 +138,7 @@ var kimchi = {
> >        */
> >       createVM : function(settings, suc, err) {
> >           kimchi.requestJSON({
> > -            url : "/vms",
> > +            url : "vms",
> >               type : "POST",
> >               contentType : "application/json",
> >               data : JSON.stringify(settings),
> > @@ -154,7 +154,7 @@ var kimchi = {
> >        */
> >       createTemplate : function(settings, suc, err) {
> >           kimchi.requestJSON({
> > -            url : "/templates",
> > +            url : "templates",
> >               type : "POST",
> >               contentType : "application/json",
> >               data : JSON.stringify(settings),
> > @@ -166,7 +166,7 @@ var kimchi = {
> >
> >       deleteTemplate : function(tem, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'templates/' + encodeURIComponent(tem),
> > +            url : 'templates/' + encodeURIComponent(tem),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -177,7 +177,7 @@ var kimchi = {
> >
> >       cloneTemplate : function(tem, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'templates/' + encodeURIComponent(tem) + "/clone",
> > +            url : 'templates/' + encodeURIComponent(tem) + "/clone",
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -188,7 +188,7 @@ var kimchi = {
> >
> >       listTemplates : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'templates',
> > +            url : 'templates',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -202,7 +202,7 @@ var kimchi = {
> >        */
> >       retrieveTemplate : function(templateName, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + "templates/" + encodeURIComponent(templateName),
> > +            url : "templates/" + encodeURIComponent(templateName),
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json'
> > @@ -216,7 +216,7 @@ var kimchi = {
> >        */
> >       updateTemplate : function(name, settings, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + "templates/" + encodeURIComponent(name),
> > +            url : "templates/" + encodeURIComponent(name),
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -232,7 +232,7 @@ var kimchi = {
> >        */
> >       createStoragePool : function(settings, suc, err) {
> >           kimchi.requestJSON({
> > -            url : '/storagepools',
> > +            url : 'storagepools',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -242,7 +242,7 @@ var kimchi = {
> >
> >       updateStoragePool : function(name, content, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + "storagepools/" + encodeURIComponent(name),
> > +            url : "storagepools/" + encodeURIComponent(name),
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -254,7 +254,7 @@ var kimchi = {
> >
> >       startVM : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/start',
> > +            url : 'vms/' + encodeURIComponent(vm) + '/start',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -265,7 +265,7 @@ var kimchi = {
> >
> >       poweroffVM : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/poweroff',
> > +            url : 'vms/' + encodeURIComponent(vm) + '/poweroff',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -276,7 +276,7 @@ var kimchi = {
> >
> >       shutdownVM : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/shutdown',
> > +            url : 'vms/' + encodeURIComponent(vm) + '/shutdown',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -287,7 +287,7 @@ var kimchi = {
> >
> >       resetVM : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/reset',
> > +            url : 'vms/' + encodeURIComponent(vm) + '/reset',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -305,7 +305,7 @@ var kimchi = {
> >        */
> >       retrieveVM : function(vm, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm),
> > +            url : 'vms/' + encodeURIComponent(vm),
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -319,7 +319,7 @@ var kimchi = {
> >        */
> >       updateVM : function(name, settings, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + "vms/" + encodeURIComponent(name),
> > +            url : "vms/" + encodeURIComponent(name),
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -331,7 +331,7 @@ var kimchi = {
> >
> >       deleteVM : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm),
> > +            url : 'vms/' + encodeURIComponent(vm),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -342,13 +342,13 @@ var kimchi = {
> >
> >       vncToVM : function(vm) {
> >           kimchi.requestJSON({
> > -            url : '/config',
> > +            url : 'config',
> >               type : 'GET',
> >               dataType : 'json'
> >           }).done(function(data, textStatus, xhr) {
> >               proxy_port = data['display_proxy_port'];
> >               kimchi.requestJSON({
> > -                url : "/vms/" + encodeURIComponent(vm) + "/connect",
> > +                url : "vms/" + encodeURIComponent(vm) + "/connect",
> >                   type : "POST",
> >                   dataType : "json"
> >               }).done(function() {
> > @@ -374,13 +374,13 @@ var kimchi = {
> >
> >       spiceToVM : function(vm) {
> >           kimchi.requestJSON({
> > -            url : '/config',
> > +            url : 'config',
> >               type : 'GET',
> >               dataType : 'json'
> >           }).done(function(data, textStatus, xhr) {
> >               proxy_port = data['display_proxy_port'];
> >               kimchi.requestJSON({
> > -                url : "/vms/" + encodeURIComponent(vm) + "/connect",
> > +                url : "vms/" + encodeURIComponent(vm) + "/connect",
> >                   type : "POST",
> >                   dataType : "json"
> >               }).done(function(data, textStatus, xhr) {
> > @@ -406,7 +406,7 @@ var kimchi = {
> >
> >       listVMs : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms',
> > +            url : 'vms',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               headers: {'Kimchi-Robot': 'kimchi-robot'},
> > @@ -419,7 +419,7 @@ var kimchi = {
> >
> >       listTemplates : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'templates',
> > +            url : 'templates',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -431,7 +431,7 @@ var kimchi = {
> >
> >       listStoragePools : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'storagepools',
> > +            url : 'storagepools',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -443,7 +443,7 @@ var kimchi = {
> >
> >       listStorageVolumes : function(poolName, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
> > +            url : 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -454,7 +454,7 @@ var kimchi = {
> >
> >       listIsos : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'storagepools/kimchi_isos/storagevolumes',
> > +            url : 'storagepools/kimchi_isos/storagevolumes',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -465,7 +465,7 @@ var kimchi = {
> >
> >       listDistros : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'config/distros',
> > +            url : 'config/distros',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -527,7 +527,7 @@ var kimchi = {
> >
> >       getTask : function(taskId, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'tasks/' + encodeURIComponent(taskId),
> > +            url : 'tasks/' + encodeURIComponent(taskId),
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -538,7 +538,7 @@ var kimchi = {
> >
> >       getTasksByFilter : function(filter, suc, err, sync) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'tasks?' + filter,
> > +            url : 'tasks?' + filter,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -550,7 +550,7 @@ var kimchi = {
> >
> >       login : function(settings, suc, err) {
> >           $.ajax({
> > -            url : "/login",
> > +            url : "login",
> >               type : "POST",
> >               contentType : "application/json",
> >               data : JSON.stringify(settings),
> > @@ -560,7 +560,7 @@ var kimchi = {
> >
> >       logout : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : '/logout',
> > +            url : 'logout',
> >               type : 'POST',
> >               contentType : "application/json",
> >               dataType : "json"
> > @@ -569,7 +569,7 @@ var kimchi = {
> >
> >       deleteStoragePool : function(poolName, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + 'storagepools/' + encodeURIComponent(poolName),
> > +            url : 'storagepools/' + encodeURIComponent(poolName),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -581,7 +581,7 @@ var kimchi = {
> >       changePoolState : function(poolName, state, suc, err) {
> >           if (state === 'activate' || state === 'deactivate')
> >               $.ajax({
> > -                url : kimchi.url + 'storagepools/' + encodeURIComponent(poolName) + '/' + state,
> > +                url : 'storagepools/' + encodeURIComponent(poolName) + '/' + state,
> >                   type : 'POST',
> >                   contentType : 'application/json',
> >                   dataType : 'json',
> > @@ -592,7 +592,7 @@ var kimchi = {
> >
> >       listPlugins : function(suc, err, sync) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'plugins',
> > +            url : 'plugins',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -605,7 +605,7 @@ var kimchi = {
> >
> >       listNetworks : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'networks',
> > +            url : 'networks',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -620,7 +620,7 @@ var kimchi = {
> >       toggleNetwork : function(name, on, suc, err) {
> >           var action = on ? "activate" : "deactivate";
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'networks/' + encodeURIComponent(name) + '/' + action,
> > +            url : 'networks/' + encodeURIComponent(name) + '/' + action,
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -633,7 +633,7 @@ var kimchi = {
> >
> >       createNetwork : function(network, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'networks',
> > +            url : 'networks',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -647,7 +647,7 @@ var kimchi = {
> >
> >       getInterfaces : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'interfaces',
> > +            url : 'interfaces',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -661,7 +661,7 @@ var kimchi = {
> >
> >       deleteNetwork : function(name, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'networks/' + encodeURIComponent(name),
> > +            url : 'networks/' + encodeURIComponent(name),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -674,7 +674,7 @@ var kimchi = {
> >
> >       listReports : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'debugreports',
> > +            url : 'debugreports',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -717,7 +717,7 @@ var kimchi = {
> >           };
> >
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'debugreports',
> > +            url : 'debugreports',
> >               type : "POST",
> >               contentType : "application/json",
> >               data : JSON.stringify(settings),
> > @@ -729,7 +729,7 @@ var kimchi = {
> >
> >       renameReport : function(name, settings, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url + "debugreports/" + encodeURIComponent(name),
> > +            url : "debugreports/" + encodeURIComponent(name),
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -742,7 +742,7 @@ var kimchi = {
> >       deleteReport: function(settings, suc, err) {
> >           var reportName = encodeURIComponent(settings['name']);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'debugreports/' + reportName,
> > +            url : 'debugreports/' + reportName,
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -757,7 +757,7 @@ var kimchi = {
> >
> >       shutdown: function(settings, suc, err) {
> >           var reboot = settings && settings['reboot'] === true;
> > -        var url = kimchi.url + 'host/' + (reboot ? 'reboot' : 'shutdown');
> > +        var url = 'host/' + (reboot ? 'reboot' : 'shutdown');
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'POST',
> > @@ -770,7 +770,7 @@ var kimchi = {
> >
> >       listHostPartitions : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/partitions',
> > +            url : 'host/partitions',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -780,7 +780,7 @@ var kimchi = {
> >       },
> >
> >       getStorageServers: function(type, suc, err) {
> > -        var url = kimchi.url + 'storageservers?_target_type=' + type;
> > +        var url = 'storageservers?_target_type=' + type;
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'GET',
> > @@ -794,7 +794,7 @@ var kimchi = {
> >       },
> >
> >       getStorageTargets: function(server,type, suc, err) {
> > -        var url = kimchi.url + 'storageservers/' + server + '/storagetargets?_target_type=' + type;
> > +        var url = 'storageservers/' + server + '/storagetargets?_target_type=' + type;
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'GET',
> > @@ -807,7 +807,7 @@ var kimchi = {
> >       },
> >
> >       getStoragePoolVolume: function(poolName, volumeName, suc, err) {
> > -        var url = kimchi.url + 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
> > +        var url = 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'GET',
> > @@ -823,7 +823,7 @@ var kimchi = {
> >           var vm = encodeURIComponent(settings['vm']);
> >           delete settings['vm'];
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + vm + '/storages',
> > +            url : 'vms/' + vm + '/storages',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -837,7 +837,7 @@ var kimchi = {
> >           var vm = encodeURIComponent(settings['vm']);
> >           var dev = encodeURIComponent(settings['dev']);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + "vms/" + vm + '/storages/' + dev,
> > +            url : "vms/" + vm + '/storages/' + dev,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -850,7 +850,7 @@ var kimchi = {
> >           var vm = encodeURIComponent(settings['vm']);
> >           var dev = encodeURIComponent(settings['dev']);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + vm + '/storages/' + dev,
> > +            url : 'vms/' + vm + '/storages/' + dev,
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify({
> > @@ -866,7 +866,7 @@ var kimchi = {
> >           var vm = settings['vm'];
> >           var dev = settings['dev'];
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/' + encodeURIComponent(vm) +
> > +            url : 'vms/' + encodeURIComponent(vm) +
> >                         '/storages/' + encodeURIComponent(dev),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> > @@ -879,7 +879,7 @@ var kimchi = {
> >       listVMStorages : function(params, suc, err) {
> >           var vm = encodeURIComponent(params['vm']);
> >           var type = params['storageType'];
> > -        var url = kimchi.url + 'vms/' + vm + '/storages';
> > +        var url = 'vms/' + vm + '/storages';
> >           if(type) {
> >               url += '?type=' + type;
> >           }
> > @@ -895,7 +895,7 @@ var kimchi = {
> >
> >       listSoftwareUpdates : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/packagesupdate',
> > +            url : 'host/packagesupdate',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -935,7 +935,7 @@ var kimchi = {
> >           };
> >
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/swupdate',
> > +            url : 'host/swupdate',
> >               type : "POST",
> >               contentType : "application/json",
> >               dataType : "json",
> > @@ -959,7 +959,7 @@ var kimchi = {
> >       retrieveRepository : function(repository, suc, err) {
> >           var reposID = encodeURIComponent(repository);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + "host/repositories/" + reposID,
> > +            url : "host/repositories/" + reposID,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -971,7 +971,7 @@ var kimchi = {
> >       updateRepository : function(name, settings, suc, err) {
> >           var reposID = encodeURIComponent(name);
> >           $.ajax({
> > -            url : kimchi.url + "host/repositories/" + reposID,
> > +            url : "host/repositories/" + reposID,
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify(settings),
> > @@ -984,7 +984,7 @@ var kimchi = {
> >       enableRepository : function(name, enable, suc, err) {
> >           var reposID = encodeURIComponent(name);
> >           $.ajax({
> > -            url : kimchi.url + "host/repositories/" + reposID +
> > +            url : "host/repositories/" + reposID +
> >                   '/' + (enable === true ? 'enable' : 'disable'),
> >               type : 'POST',
> >               contentType : 'application/json',
> > @@ -997,7 +997,7 @@ var kimchi = {
> >       deleteRepository : function(repository, suc, err) {
> >           var reposID = encodeURIComponent(repository);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/repositories/' + reposID,
> > +            url : 'host/repositories/' + reposID,
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1008,7 +1008,7 @@ var kimchi = {
> >
> >       listRepositories : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/repositories',
> > +            url : 'host/repositories',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1019,7 +1019,7 @@ var kimchi = {
> >       },
> >
> >       getHostFCDevices: function(suc, err) {
> > -        var url = kimchi.url+'host/devices?_cap=fc_host';
> > +        var url = 'host/devices?_cap=fc_host';
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'GET',
> > @@ -1033,7 +1033,7 @@ var kimchi = {
> >       },
> >
> >       getGuestInterfaces: function(name, suc, err) {
> > -        var url = kimchi.url+'vms/'+encodeURIComponent(name)+'/ifaces';
> > +        var url = 'vms/'+encodeURIComponent(name)+'/ifaces';
> >           kimchi.requestJSON({
> >               url : url,
> >               type : 'GET',
> > @@ -1048,7 +1048,7 @@ var kimchi = {
> >
> >       createGuestInterface : function(name, interface, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(name)+'/ifaces',
> > +            url : 'vms/'+encodeURIComponent(name)+'/ifaces',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1062,7 +1062,7 @@ var kimchi = {
> >
> >       deleteGuestInterface : function(vm, mac, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> > +            url : 'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1075,7 +1075,7 @@ var kimchi = {
> >
> >       updateGuestInterface : function(vm, mac, interface, suc, err) {
> >           $.ajax({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> > +            url : 'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> >               type : 'PUT',
> >               contentType : 'application/json',
> >               data : JSON.stringify(interface),
> > @@ -1089,7 +1089,7 @@ var kimchi = {
> >
> >       getUserById : function(data, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'users?_user_id=' + data.user_id,
> > +            url : 'users?_user_id=' + data.user_id,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1104,7 +1104,7 @@ var kimchi = {
> >
> >       getUsers : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'users',
> > +            url : 'users',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1118,7 +1118,7 @@ var kimchi = {
> >
> >       getGroups : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'groups',
> > +            url : 'groups',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1132,7 +1132,7 @@ var kimchi = {
> >
> >       getHostPCIDevices : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/devices?_passthrough=true&_cap=pci',
> > +            url : 'host/devices?_passthrough=true&_cap=pci',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1146,7 +1146,7 @@ var kimchi = {
> >
> >       getPCIDeviceCompanions : function(pcidev, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/devices?_passthrough_affected_by=' + pcidev,
> > +            url : 'host/devices?_passthrough_affected_by=' + pcidev,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1162,7 +1162,7 @@ var kimchi = {
> >           server = encodeURIComponent(server);
> >           port = port ? '&_server_port='+encodeURIComponent(port) : '';
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi'+port,
> > +            url : 'storageservers/'+server+'/storagetargets?_target_type=iscsi'+port,
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1176,7 +1176,7 @@ var kimchi = {
> >
> >       getPeers : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'peers',
> > +            url : 'peers',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1190,7 +1190,7 @@ var kimchi = {
> >
> >       getVMPCIDevices : function(id, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/'+encodeURIComponent(id)+'/hostdevs',
> > +            url : 'vms/'+encodeURIComponent(id)+'/hostdevs',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1204,7 +1204,7 @@ var kimchi = {
> >
> >       addVMPCIDevice : function(vm, device, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/'+ encodeURIComponent(vm) +'/hostdevs',
> > +            url : 'vms/'+ encodeURIComponent(vm) +'/hostdevs',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1218,7 +1218,7 @@ var kimchi = {
> >
> >       removeVMPCIDevice : function(vm, device, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/'+ encodeURIComponent(vm) +'/hostdevs/' + encodeURIComponent(device),
> > +            url : 'vms/'+ encodeURIComponent(vm) +'/hostdevs/' + encodeURIComponent(device),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1236,7 +1236,7 @@ var kimchi = {
> >           var fd = settings['formData'];
> >           var sp = encodeURIComponent(settings['sp']);
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'storagepools/' + sp + '/storagevolumes',
> > +            url : 'storagepools/' + sp + '/storagevolumes',
> >               type : 'POST',
> >               data : fd,
> >               processData : false,
> > @@ -1254,7 +1254,7 @@ var kimchi = {
> >           var sp = encodeURIComponent(settings['sp']);
> >           delete settings['sp'];
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'storagepools/' + sp + '/storagevolumes',
> > +            url : 'storagepools/' + sp + '/storagevolumes',
> >               type : 'POST',
> >               data : JSON.stringify(settings),
> >               contentType : 'application/json',
> > @@ -1266,7 +1266,7 @@ var kimchi = {
> >
> >       cloneGuest: function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'vms/'+encodeURIComponent(vm)+"/clone",
> > +            url : 'vms/'+encodeURIComponent(vm)+"/clone",
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1279,7 +1279,7 @@ var kimchi = {
> >
> >       listSnapshots : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/snapshots',
> > +            url : 'vms/'+encodeURIComponent(vm)+'/snapshots',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1293,7 +1293,7 @@ var kimchi = {
> >
> >       getCurrentSnapshot : function(vm, suc, err, sync) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/snapshots/current',
> > +            url : 'vms/'+encodeURIComponent(vm)+'/snapshots/current',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1308,7 +1308,7 @@ var kimchi = {
> >
> >       revertSnapshot : function(vm, snapshot, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot)+'/revert',
> > +            url : 'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot)+'/revert',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1321,7 +1321,7 @@ var kimchi = {
> >
> >       createSnapshot : function(vm, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/snapshots',
> > +            url : 'vms/'+encodeURIComponent(vm)+'/snapshots',
> >               type : 'POST',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1334,7 +1334,7 @@ var kimchi = {
> >
> >       deleteSnapshot : function(vm, snapshot, suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot),
> > +            url : 'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot),
> >               type : 'DELETE',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > @@ -1347,7 +1347,7 @@ var kimchi = {
> >
> >       getCPUInfo : function(suc, err) {
> >           kimchi.requestJSON({
> > -            url : kimchi.url + 'host/cpuinfo',
> > +            url : 'host/cpuinfo',
> >               type : 'GET',
> >               contentType : 'application/json',
> >               dataType : 'json',
> > diff --git a/ui/js/src/kimchi.login.js b/ui/js/src/kimchi.login.js
> > index 19b8691..556fbda 100644
> > --- a/ui/js/src/kimchi.login.js
> > +++ b/ui/js/src/kimchi.login.js
> > @@ -57,7 +57,7 @@ kimchi.login_main = function() {
> >                   var next_url = lastPage ? lastPage.replace(/\"/g,'') : "/";
> >               }
> >               kimchi.cookie.set('roles',JSON.stringify(data.roles));
> > -            window.location.replace(next_url)
> > +            window.location.replace(window.location.pathname.replace(/\/+login.html/, '') + next_url)
> >           }, function() {
> >               $("#messUserPass").show();
> >               $("#messSession").hide();
> > diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl
> > index 3cc2fad..7051ed5 100644
> > --- a/ui/pages/guest.html.tmpl
> > +++ b/ui/pages/guest.html.tmpl
> > @@ -45,7 +45,7 @@
> >                   <div class="tile ">
> >                       <img class="imgactive" alt="" src="">
> >                       <img class="imgload" alt="" src="">
> > -                    <img class="overlay shutoff-hidden" alt="$_("Start")" src="/images/theme-default/icon-power-down.png" >
> > +                    <img class="overlay shutoff-hidden" alt="$_("Start")" src="images/theme-default/icon-power-down.png" >
> >                   </div>
> >               </div>
> >              <div class="sortable guest-actions" name="guest-actions">
> > diff --git a/ui/pages/help/dita-help.xsl b/ui/pages/help/dita-help.xsl
> > index 9cfeeea..8583a4e 100644
> > --- a/ui/pages/help/dita-help.xsl
> > +++ b/ui/pages/help/dita-help.xsl
> > @@ -9,8 +9,8 @@
> >               <head>
> >                   <title><xsl:value-of select="/cshelp/title" /></title>
> >                   <meta charset="UTF-8" />
> > -                <link rel="shortcut icon" href="/images/logo.ico" />
> > -                <link rel="stylesheet" type="text/css" href="/help/kimchi.css" />
> > +                <link rel="shortcut icon" href="../../images/logo.ico" />
> > +                <link rel="stylesheet" type="text/css" href="../kimchi.css" />
> >               </head>
> >               <body>
> >                   <xsl:apply-templates select="//cshelp" />
> > diff --git a/ui/pages/kimchi-ui.html.tmpl b/ui/pages/kimchi-ui.html.tmpl
> > index 844234d..2366d67 100644
> > --- a/ui/pages/kimchi-ui.html.tmpl
> > +++ b/ui/pages/kimchi-ui.html.tmpl
> > @@ -118,7 +118,7 @@
> >   <script id="about-tmpl" type="kimchi/template">
> >       <div class="window about-window">
> >           <header>
> > -            <h1 class="title"><img alt="Kimchi logo" src="/images/logo.ico"/> $_("About")</h1>
> > +            <h1 class="title"><img alt="Kimchi logo" src="images/logo.ico"/> $_("About")</h1>
> >               <div class="close">X</div>
> >           </header>
> >           <div class="content" align="center">
> > @@ -126,7 +126,7 @@
> >                   <div>
> >                       <br/>
> >                       <br/>
> > -                    <img src="/images/theme-default/logo-plain.gif"/>
> > +                    <img src="images/theme-default/logo-plain.gif"/>
> >                       <br/>
> >                       <br/>
> >                       <h2>Kimchi</h2>
> > diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
> > index 081805b..8ed77a6 100644
> > --- a/ui/pages/storagepool-add.html.tmpl
> > +++ b/ui/pages/storagepool-add.html.tmpl
> > @@ -100,7 +100,7 @@
> >                           <div class="host-partition">
> >                               <p class="text-help">
> >                                   $_("Looking for available partitions ...")
> > -                                <img src = "../images/theme-default/loading.gif" />
> > +                                <img src = "images/theme-default/loading.gif" />
> >                               </p>
> >                           </div>
> >                       </section>
> > diff --git a/ui/pages/tabs/storage.html.tmpl b/ui/pages/tabs/storage.html.tmpl
> > index dbbaef9..df4636c 100644
> > --- a/ui/pages/tabs/storage.html.tmpl
> > +++ b/ui/pages/tabs/storage.html.tmpl
> > @@ -43,7 +43,7 @@
> >   </div>
> >   <div id="logicalPoolExtend" title="$_("Device path")">
> >        <p id="loading-info" class="text-help">
> > -         <img src = "../images/theme-default/loading.gif" />
> > +         <img src = "images/theme-default/loading.gif" />
> >            $_("Looking for available partitions ...")
> >        </p>
> >        <div class="host-partition">
> > diff --git a/ui/pages/template-add.html.tmpl b/ui/pages/template-add.html.tmpl
> > index eaafaa7..f5c5a75 100644
> > --- a/ui/pages/template-add.html.tmpl
> > +++ b/ui/pages/template-add.html.tmpl
> > @@ -145,7 +145,7 @@
> >                   <div id="load-remote-iso">
> >                       <h3 class="step-subtitle">
> >                           <label>
> > -                            <img src = "../images/theme-default/loading.gif" />
> > +                            <img src = "images/theme-default/loading.gif" />
> >                               $_("Loading default remote ISOs ...")
> >                           </label>
> >                       </h3>
> 
> 




More information about the Kimchi-devel mailing list