1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Alvaro Lopez Ortega <alvaro@alobbs.com>
7 * Stefan de Konink <stefan@konink.de>
9 * Copyright (C) 2001-2008 Alvaro Lopez Ortega
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 // #define LINUX_CMDLINE "root=/dev/xvda ro ip=%s:1.2.3.4:%s:%s::eth0:off"
28 #define VIRT_INTERFACE_XML \
29 " <interface type='bridge'>" \
30 " <source bridge='xenbr0'/>" \
31 " <mac address='%s'/>" \
32 " <ip address='%s' />" \
33 " <script path='vif-bridge'/>" \
36 //" <target dev='vif1.0'/>" \
38 #define VIRT_DISK_XML \
39 " <disk type='file' device='disk'>" \
40 " <driver name='tap' type='qcow' />" \
41 " <source file='%s'/>" \
42 " <target dev='%s' bus='xen'/>" \
47 #define VIRT_DOMAIN_XML \
48 "<domain type='xen'>" \
49 " <name>%s_%s</name>" \
51 " <type>linux</type>" \
52 " <kernel>/usr/lib/xen/boot/linux-2.6.20-xen-r6</kernel>" \
53 " <cmdline> root=/dev/xvda ro</cmdline>" \
55 " <memory>%d</memory>" \
57 " <on_poweroff>destroy</on_poweroff>" \
58 " <on_reboot>restart</on_reboot>" \
59 " <on_crash>destroy</on_crash>" \
65 #define VIRT_STORAGE_XML \
66 "<volume type='%s'>" \
68 " <allocation>%lu</allocation>" \
69 " <capacity unit='%s'>%lu</capacity>" \
71 " <path>%s/%s/images/%s</path>" \
73 " <owner>0744</owner>" \
74 " <group>0744</group>" \
75 " <mode>0744</mode>" \
76 " <label>%s_%s</label>" \
82 #include "handler_virt.h"
83 #include "handler_avahi.h"
84 #include <cherokee/cherokee.h>
86 /* Plug-in initialization
88 * In this function you can use any of these:
89 * http_delete | http_get | http_post | http_put
91 * For a full list: cherokee_http_method_t
93 * It is what your handler to be implements.
96 PLUGIN_INFO_HANDLER_EASIEST_INIT (virt
, http_get
| http_post
);
99 /* Methods implementation
102 props_free (cherokee_handler_virt_props_t
*props
)
105 cherokee_buffer_mrproper(&props
->xsl
);
106 cherokee_buffer_mrproper(&props
->virt
);
107 return cherokee_module_props_free_base (MODULE_PROPS(props
));
112 cherokee_handler_virt_configure (cherokee_config_node_t
*conf
, cherokee_server_t
*srv
, cherokee_module_props_t
**_props
)
115 cherokee_handler_virt_props_t
*props
;
117 /* Instance a new property object
120 if (*_props
== NULL
) {
121 CHEROKEE_NEW_STRUCT (n
, handler_virt_props
);
123 cherokee_handler_avahi_props_init_base (PROP_AVAHI(n
), MODULE_PROPS_FREE(props_free
));
125 /* Look at handler_virt.h
126 * This is an virt of configuration.
128 n
->authenticate
= true; /* by default we are secure! */
129 n
->read_only
= true; /* by default we are secure! */
130 cherokee_buffer_init (&n
->xsl
); /* we support a custom header */
131 cherokee_buffer_init (&n
->virt
); /* your first xenserver */
133 *_props
= MODULE_PROPS(n
);
136 props
= PROP_VIRT(*_props
);
138 cherokee_config_node_foreach (i
, conf
) {
139 cherokee_config_node_t
*subconf
= CONFIG_NODE(i
);
141 if (equal_buf_str (&subconf
->key
, "authenticate")) {
142 props
->authenticate
= atoi(subconf
->val
.buf
);
144 else if (equal_buf_str (&subconf
->key
, "read_only")) {
145 props
->read_only
= atoi(subconf
->val
.buf
);
147 else if (equal_buf_str (&subconf
->key
, "xsl")) {
148 cherokee_buffer_add_buffer (&props
->xsl
, &subconf
->val
);
150 else if (equal_buf_str (&subconf
->key
, "virt")) {
151 cherokee_buffer_add_buffer (&props
->virt
, &subconf
->val
);
159 return cherokee_handler_avahi_configure (conf
, srv
, _props
);
164 cherokee_handler_virt_init (cherokee_handler_virt_t
*hdl
)
170 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
171 cherokee_buffer_init(&hdl
->user
);
172 cherokee_buffer_init(&hdl
->vm
);
174 hdl
->action
= nothing
;
176 cherokee_buffer_add (&conn
->pathinfo
,
177 conn
->request
.buf
+ conn
->web_directory
.len
,
178 conn
->request
.len
- conn
->web_directory
.len
);
180 this = conn
->pathinfo
.buf
+ 1;
181 next
= strchr(this, '/');
184 if ((!next
&& (this && (len
= strlen(this)) == 0)) || (next
&& ((len
= next
- this) == 0)) )
185 hdl
->action
= showall
;
187 cherokee_buffer_add (&hdl
->user
, this, len
);
190 if (HDL_VIRT_PROPS(hdl
)->authenticate
) {
191 if (!conn
->validator
||
193 (!cherokee_buffer_cmp_buf(&conn
->validator
->user
, &hdl
->user
) &&
194 !(isroot
= cherokee_buffer_cmp (&conn
->validator
->user
, "root", 4))))) {
195 hdl
->action
= nothing
; /* just in case */
196 conn
->error_code
= http_unauthorized
;
203 if (hdl
->action
== showall
) {
205 hdl
->action
= nothing
;
206 conn
->error_code
= http_unauthorized
;
209 return virt_build_page(hdl
);
215 hdl
->action
= showuservms
;
216 return virt_build_page(hdl
);
219 next
= strchr(this, '/');
221 if (!next
&& (this && (len
= strlen(this)) == 0) || (next
&& ((len
= next
- this) == 0)) ) {
222 hdl
->action
= showuservms
;
223 return virt_build_page(hdl
);
227 cherokee_buffer_add (&hdl
->vm
, this, len
);
230 hdl
->action
= domainGetXMLDesc
;
231 return virt_build_page(hdl
);
234 next
= strchr(this, '/');
236 if (!next
&& (this && (len
= strlen(this)) == 0) || (next
&& ((len
= next
- this) == 0)) ) {
237 hdl
->action
= domainGetXMLDesc
;
238 return virt_build_page(hdl
);
242 hdl
->action
= not_implemented
;
243 switch (conn
->header
.method
) {
245 if (strncmp(this, "virDomain", 9) == 0) {
246 if (strncmp(this+9, "Get", 3) == 0) {
247 if (strcmp(this+12, "ID") == 0) hdl
->action
= domainGetID
;
248 else if (strcmp(this+12, "Name") == 0) hdl
->action
= domainGetName
;
249 else if (strcmp(this+12, "MaxMemory") == 0) hdl
->action
= domainGetMaxMemory
;
250 else if (strcmp(this+12, "MaxVcpus") == 0) hdl
->action
= domainGetMaxVcpus
;
251 else if (strcmp(this+12, "OSType") == 0) hdl
->action
= domainGetOSType
;
252 else if (strcmp(this+12, "UUID") == 0) hdl
->action
= domainGetUUID
;
253 else if (strcmp(this+12, "UUIDString") == 0) hdl
->action
= domainGetUUIDString
;
254 else if (strcmp(this+12, "XMLDesc") == 0) hdl
->action
= domainGetXMLDesc
;
256 else if (strcmp(this+9, "Create") == 0) hdl
->action
= domainCreate
;
257 else if (strcmp(this+9, "Destroy") == 0) hdl
->action
= domainDestroy
;
258 else if (strcmp(this+9, "Reboot") == 0) hdl
->action
= domainReboot
;
259 else if (strcmp(this+9, "Shutdown") == 0) hdl
->action
= domainShutdown
;
261 else if (strcmp(this+9, "AttachDevice") == 0) hdl
->action
= domainAttachDevice_args
;
263 else if (strcmp(this+9, "DefineXML") == 0) hdl
->action
= domainDefineXML_args
;
264 else if (strcmp(this+9, "Undefine") == 0) hdl
->action
= domainUndefine
;
266 else if (strncmp(this, "virStorage", 10) == 0) {
267 if (strncmp(this+10, "Vol", 3) == 0) {
268 if (strcmp(this+13, "CreateXML") == 0) hdl
->action
= storageVolCreateXML_args
;
269 if (strcmp(this+13, "CloneXML") == 0) hdl
->action
= storageVolCloneXML_args
;
276 cherokee_post_get_len (&conn
->post
, &postl
);
278 if (postl
<= 0 || postl
>= (INT_MAX
-1)) {
279 conn
->error_code
= http_bad_request
;
283 if (strncmp(this, "virDomain", 9) == 0) {
284 if (strcmp(this+9, "AttachDevice") == 0) hdl
->action
= domainAttachDevice
;
285 else if (strcmp(this+9, "DetachDevice") == 0) hdl
->action
= domainDetachDevice
;
286 else if (strcmp(this+9, "DefineXML") == 0) hdl
->action
= domainDefineXML
;
288 else if (strncmp(this, "virStorage", 10) == 0) {
289 if (strncmp(this+10, "Vol", 3) == 0) {
290 if (strcmp(this+13, "CreateXML") == 0) hdl
->action
= storageVolCreateXML
;
301 if (hdl
->action
<= 0) {
302 conn
->error_code
= http_bad_request
;
307 return virt_build_page(hdl
);
311 cherokee_handler_virt_free (cherokee_handler_virt_t
*hdl
)
313 cherokee_buffer_mrproper (&hdl
->buffer
);
314 cherokee_buffer_mrproper (&hdl
->user
);
315 cherokee_buffer_mrproper (&hdl
->vm
);
321 cherokee_handler_virt_step (cherokee_handler_virt_t
*hdl
, cherokee_buffer_t
*buffer
)
323 cherokee_buffer_add_buffer (buffer
, &hdl
->buffer
);
324 return ret_eof_have_data
;
328 cherokee_handler_virt_add_headers (cherokee_handler_virt_t
*hdl
, cherokee_buffer_t
*buffer
)
330 cherokee_buffer_add_va (buffer
, "Content-Length: %d"CRLF
, hdl
->buffer
.len
);
332 if (hdl
->action
> xml
)
333 cherokee_buffer_add_str (buffer
, "Content-Type: application/xml"CRLF
);
335 cherokee_buffer_add_str (buffer
, "Content-Type: text/plain"CRLF
);
342 while_func_entries (cherokee_buffer_t *key, void *value, void *param) {
343 virConnectPtr conn = NULL;
344 cherokee_buffer_t uri = CHEROKEE_BUF_INIT;
345 cherokee_buffer_t *buf = (cherokee_buffer_t *)param;
347 cherokee_buffer_add_va (&uri, "xen://%s/", value);
349 if (HDL_VIRT_PROPS(hdl)->read_only == FALSE && !(conn = virConnectOpen (uri.buf))) {
350 if (!(conn = virConnectOpen (uri.buf))) {
355 if (!conn && !(conn = virConnectOpenReadOnly (uri.buf))) {
359 if (!(dom = virDomainLookupByName(conn, (const char *) key->buf))) {
362 char *xml = virDomainGetXMLDesc(dom, 0);
363 cherokee_buffer_add(buf, xml, strlen(xml));
365 virConnectClose(conn);
368 cherokee_buffer_mrproper(&uri);
374 virt_virt_function(cherokee_handler_virt_t
*hdl
, virDomainPtr dom
) {
375 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
376 cherokee_buffer_t
*buf
= &HDL_AVAHI(hdl
)->buffer
;
378 switch (hdl
->action
) {
380 case domainUndefine
: {
382 if ((result
= virDomainUndefine(dom
)) != 0) {
383 conn
->error_code
= http_internal_error
;
386 cherokee_buffer_add_long10(buf
, result
);
390 case domainAttachDevice_args
: {
394 ret
= cherokee_connection_parse_args (conn
);
395 if (unlikely(ret
< ret_ok
))
398 ret
= cherokee_avl_get_ptr (conn
->arguments
, "type", &temp
);
401 cherokee_buffer_t xml
= CHEROKEE_BUF_INIT
;
403 if (strcmp(temp
, "disk") == 0) {
406 if ((ret
= cherokee_avl_get_ptr (conn
->arguments
, "file", &file
)) == ret_ok
&& (ret
= cherokee_avl_get_ptr (conn
->arguments
, "device", &device
)) == ret_ok
) {
407 cherokee_buffer_add_va (&xml
, VIRT_DISK_XML
, file
, device
);
413 else if (strcmp(temp
, "interface") == 0) {
415 if ((ret
= cherokee_avl_get_ptr (conn
->arguments
, "mac", &mac
)) == ret_ok
&& (ret
= cherokee_avl_get_ptr (conn
->arguments
, "ip", &ip
)) == ret_ok
) {
416 cherokee_buffer_add_va (&xml
, VIRT_INTERFACE_XML
, mac
, ip
);
420 cherokee_buffer_t domu
= CHEROKEE_BUF_INIT
;
421 cherokee_buffer_add_va (&domu
, "%s_%s", hdl
->user
.buf
, hdl
->vm
.buf
);
422 getNewMac("dv28", domu
.buf
, &mac
, &ip
);
423 cherokee_buffer_mrproper(&domu
);
424 cherokee_buffer_add_va (&xml
, VIRT_INTERFACE_XML
, mac
, ip
);
430 if (ret
== ret_ok
&& (result
= virDomainAttachDevice(dom
, (const char *) xml
.buf
)) == 0) {
433 conn
->error_code
= http_internal_error
;
437 cherokee_buffer_add_long10(buf
, result
);
438 cherokee_buffer_mrproper(&xml
);
444 case domainAttachDevice
: {
447 cherokee_buffer_t post
= CHEROKEE_BUF_INIT
;
448 cherokee_post_get_len (&conn
->post
, &postl
);
449 cherokee_post_walk_read (&conn
->post
, &post
, (cuint_t
) postl
);
450 if ((result
= virDomainAttachDevice(dom
, (const char *) post
.buf
)) != 0)
451 conn
->error_code
= http_internal_error
;
453 cherokee_buffer_mrproper(&post
);
454 cherokee_buffer_add_long10(buf
, result
);
459 case domainGetXMLDesc
: {
460 char *xml
= virDomainGetXMLDesc(dom
, 0);
461 cherokee_buffer_add(buf
, xml
, strlen(xml
));
467 case domainDetachDevice
: {
470 cherokee_buffer_t post
= CHEROKEE_BUF_INIT
;
471 cherokee_post_get_len (&conn
->post
, &postl
);
472 cherokee_post_walk_read (&conn
->post
, &post
, (cuint_t
) postl
);
473 if ((result
= virDomainDetachDevice(dom
, (const char *) post
.buf
)) != 0) {
474 conn
->error_code
= http_internal_error
;
476 cherokee_buffer_mrproper(&post
);
477 cherokee_buffer_add_long10(buf
, result
);
482 cherokee_buffer_add_ulong10(buf
, virDomainGetID(dom
));
485 case domainGetMaxMemory
: {
486 cherokee_buffer_add_ulong10(buf
, virDomainGetMaxMemory (dom
));
489 case domainGetMaxVcpus
: {
490 cherokee_buffer_add_long10(buf
, virDomainGetMaxVcpus (dom
));
493 case domainGetName
: {
494 const char *name
= virDomainGetName (dom
);
495 cherokee_buffer_add(buf
, name
, strlen(name
));
498 case domainGetUUID
: {
499 unsigned char uuid
[VIR_UUID_BUFLEN
];
500 if (virDomainGetUUID(dom
, uuid
) == 0) {
501 cherokee_buffer_add_str(buf
, uuid
);
503 conn
->error_code
= http_internal_error
;
508 case domainGetUUIDString
: {
509 unsigned char uuid
[VIR_UUID_STRING_BUFLEN
];
510 if (virDomainGetUUIDString(dom
, uuid
) == 0) {
511 cherokee_buffer_add_str(buf
, uuid
);
513 conn
->error_code
= http_internal_error
;
520 cherokee_buffer_add_long10(buf
, virDomainCreate (dom
));
524 case domainDestroy
: {
525 cherokee_buffer_add_long10(buf
, virDomainDestroy (dom
));
530 cherokee_buffer_add_long10(buf
, virDomainReboot (dom
, 0));
534 case domainShutdown
: {
535 cherokee_buffer_add_long10(buf
, virDomainShutdown (dom
));
540 case domainGetOSType
: {
541 char *ostype
= virDomainGetOSType(dom
);
542 cherokee_buffer_add(buf
, ostype
, strlen(ostype
));
553 virt_virt_new(cherokee_handler_virt_t
*hdl
, virConnectPtr virConn
)
555 cherokee_buffer_t
*buf
= &HDL_AVAHI(hdl
)->buffer
;
556 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
557 cherokee_buffer_t xml
= CHEROKEE_BUF_INIT
;
559 virStoragePoolPtr pool
;
560 virStorageVolPtr volume
;
562 switch (hdl
->action
) {
563 case storageVolCloneXML_args
: {
567 ret
= cherokee_connection_parse_args (conn
);
568 if (unlikely(ret
< ret_ok
)) {
569 conn
->error_code
= http_internal_error
;
573 ret
= cherokee_avl_get_ptr (conn
->arguments
, "pool", &temp
);
574 if (unlikely(ret
< ret_ok
)) {
575 conn
->error_code
= http_bad_request
;
579 pool
= virStoragePoolLookupByName(virConn
, temp
);
582 conn
->error_code
= http_not_found
;
586 ret
= cherokee_avl_get_ptr (conn
->arguments
, "volume", &temp
);
587 if (unlikely(ret
< ret_ok
)) {
588 conn
->error_code
= http_bad_request
;
592 volume
= virStorageVolLookupByName(pool
, temp
);
594 if (volume
== NULL
) {
595 conn
->error_code
= http_not_found
;
599 source
= virStorageVolGetKey(volume
);
601 ret
= cherokee_avl_get_ptr (conn
->arguments
, "name", &name
);
602 if (unlikely(ret
< ret_ok
)) {
603 virStorageVolFree(volume
);
604 virStoragePoolFree(pool
);
605 conn
->error_code
= http_bad_request
;
609 ret
= cherokee_avl_get_ptr (conn
->arguments
, "type", &temp
);
610 if (unlikely(ret
< ret_ok
)) {
611 virStorageVolFree(volume
);
612 virStoragePoolFree(pool
);
613 conn
->error_code
= http_bad_request
;
617 enum { UNKNOWN
, RAW
, QCOW
} clone
= UNKNOWN
;
619 if (strcmp("raw", temp
) == 0)
621 else if (strcmp("qcow", temp
) == 0)
624 virStorageVolFree(volume
);
625 virStoragePoolFree(pool
);
626 conn
->error_code
= http_bad_request
;
630 cherokee_buffer_t busy
= CHEROKEE_BUF_INIT
;
631 cherokee_buffer_add_va (&busy
, "/mnt/netapp/images/%s_%s.queued", hdl
->user
.buf
, name
);
633 if (unlikely(symlink(source
, busy
.buf
) == 1)) {
634 virStorageVolFree(volume
);
635 virStoragePoolFree(pool
);
636 conn
->error_code
= http_internal_error
;
640 cherokee_buffer_mrproper(&busy
);
641 cherokee_buffer_add_str(buf
, "BUSY");
646 case storageVolCreateXML_args
: {
647 void *temp
, *type
, *name
, *unit
;
649 unsigned long int capacity
, allocation
;
651 ret
= cherokee_connection_parse_args (conn
);
652 if (unlikely(ret
< ret_ok
))
655 ret
= cherokee_avl_get_ptr (conn
->arguments
, "pool", &temp
);
656 if (unlikely(ret
< ret_ok
))
659 pool
= virStoragePoolLookupByName(virConn
, temp
);
664 pool_path
= "/mnt/netapp/users";
666 pool_path = virStoragePoolGetPath(pool);
669 virStoragePoolFree(pool);
675 ret
= cherokee_avl_get_ptr (conn
->arguments
, "name", &name
);
676 if (unlikely(ret
< ret_ok
))
679 ret
= cherokee_avl_get_ptr (conn
->arguments
, "type", &type
);
680 if (unlikely(ret
< ret_ok
))
683 ret
= cherokee_avl_get_ptr (conn
->arguments
, "unit", &unit
);
684 if (unlikely(ret
< ret_ok
))
687 ret
= cherokee_avl_get_ptr (conn
->arguments
, "allocation", &temp
);
688 if (unlikely(ret
< ret_ok
))
691 allocation
= strtoul(temp
, NULL
, 10);
692 /* TODO: errno check */
694 ret
= cherokee_avl_get_ptr (conn
->arguments
, "capacity", &temp
);
695 if (unlikely(ret
< ret_ok
))
698 capacity
= strtoul(temp
, NULL
, 10);
699 /* TODO: errno check */
701 cherokee_buffer_add_va (&xml
, VIRT_STORAGE_XML
, type
, name
, allocation
, unit
, capacity
, pool_path
, hdl
->user
.buf
, name
, hdl
->user
.buf
, name
);
706 case domainDefineXML_args
: {
709 unsigned long vcpu
= 0, interface
= 0, memory
= 0;
711 cherokee_buffer_t xml_interfaces
= CHEROKEE_BUF_INIT
;
714 ret
= cherokee_connection_parse_args (conn
);
715 if (unlikely(ret
< ret_ok
))
718 ret
= cherokee_avl_get_ptr (conn
->arguments
, "vcpu", &temp
);
720 vcpu
= strtoul(temp
, (char **) NULL
, 10);
722 if (ret
!= ret_ok
|| errno
== ERANGE
|| vcpu
== 0) {
723 conn
->error_code
= http_internal_error
;
728 ret
= cherokee_avl_get_ptr (conn
->arguments
, "memory", &temp
);
730 memory
= strtoul(temp
, (char **) NULL
, 10);
732 if (ret
!= ret_ok
|| errno
== ERANGE
|| memory
== 0) {
733 conn
->error_code
= http_internal_error
;
738 ret
= cherokee_avl_get_ptr (conn
->arguments
, "interface", &temp
);
740 interface
= strtoul(temp
, (char **) NULL
, 10);
742 if (ret
!= ret_ok
|| errno
== ERANGE
) {
743 conn
->error_code
= http_internal_error
;
747 cherokee_buffer_t domu
= CHEROKEE_BUF_INIT
;
748 cherokee_buffer_add_va (&domu
, "%s_%s", hdl
->user
.buf
, hdl
->vm
.buf
);
750 for (i
= 0; i
< interface
; i
++) {
753 getNewMac("dv28", domu
.buf
, &mac
, &ip
);
754 cherokee_buffer_add_va (&xml_interfaces
, VIRT_INTERFACE_XML
, mac
, ip
);
757 cherokee_buffer_mrproper(&domu
);
759 cherokee_buffer_add_va (&xml
, VIRT_DOMAIN_XML
,
760 hdl
->user
.buf
, hdl
->vm
.buf
, memory
, vcpu
, xml_interfaces
.buf
);
762 cherokee_buffer_mrproper(&xml_interfaces
);
766 case storageVolCreateXML
:
767 case domainDefineXML
: {
769 cherokee_post_get_len (&conn
->post
, &postl
);
770 cherokee_post_walk_read (&conn
->post
, &xml
, (cuint_t
) postl
);
775 switch (hdl
->action
) {
776 case domainDefineXML_args
:
777 case domainDefineXML
: {
778 result
= virDomainDefineXML(virConn
, (const char *) xml
.buf
);
779 // printf("%s\n", xml.buf);
780 cherokee_buffer_mrproper(&xml
);
782 if (result
== NULL
) {
783 /* TODO: vrij maken eventuele uitgegeven macs! */
784 conn
->error_code
= http_internal_error
;
789 if ((fd
= fopen("/mnt/netapp/users/%s/%s.xml", "w")) == NULL
) {
790 /* eigenlijk alles opschonen... */
791 conn
->error_code
= http_internal_error
;
794 char *output
= virDomainGetXMLDesc(result
, 0);
795 fwrite(output
, strlen(output
), sizeof(char), fd
);
797 cherokee_buffer_add(buf
, output
, strlen(output
));
803 case storageVolCreateXML_args
:
804 case storageVolCreateXML
: {
805 printf("%s", &xml
.buf
);
807 virStorageVolPtr vol
= virStorageVolCreateXML(pool
, (const char *) &xml
.buf
, 0);
808 virStoragePoolFree(pool
);
809 cherokee_buffer_mrproper(&xml
);
814 cherokee_buffer_add_long10(buf
, 0);
824 virt_virt_do(cherokee_handler_virt_t
*hdl
, cherokee_buffer_t
*domu
, cherokee_buffer_t
*uri
)
826 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
828 ret_t ret
= ret_error
;
829 virConnectPtr virConn
= NULL
;
832 if (HDL_VIRT_PROPS(hdl
)->read_only
== FALSE
)
833 virConn
= virConnectOpen (uri
->buf
);
835 if (!virConn
&& !(virConn
= virConnectOpenReadOnly (uri
->buf
))) {
836 conn
->error_code
= http_service_unavailable
;
840 switch (hdl
->action
) {
841 case storageVolCloneXML_args
:
842 case storageVolCreateXML_args
:
843 case storageVolCreateXML
:
844 case domainDefineXML_args
:
845 case domainDefineXML
: {
846 ret
= virt_virt_new(hdl
, virConn
);
852 if ((dom
= virDomainLookupByName(virConn
, domu
->buf
)) == NULL
) {
853 conn
->error_code
= http_not_found
;
855 ret
= virt_virt_function(hdl
, dom
);
861 virConnectClose(virConn
);
866 virt_while (cherokee_buffer_t
*key
, void *value
, void *param
) {
867 cherokee_handler_virt_t
* hdl
= param
;
868 // cherokee_buffer_t uri = CHEROKEE_BUF_INIT;
869 // cherokee_buffer_add_va (&uri, "xen://%s/", ((cherokee_buffer_t *) value)->buf);
870 // virt_virt_do((cherokee_handler_virt_t *) param, key, &uri);
871 // cherokee_buffer_mrproper(&uri);
873 cherokee_buffer_add_va (&hdl
->buffer
, "<domain><name>%s</name></domain>", key
->buf
);
879 virt_while_user (cherokee_buffer_t
*key
, void *value
, void *param
) {
880 cherokee_handler_virt_t
*hdl
= param
;
881 if (key
->len
> hdl
->user
.len
&& key
->buf
[hdl
->user
.len
] == '_' && strncmp(key
->buf
, hdl
->user
.buf
, hdl
->user
.len
) == 0)
882 return virt_while (key
, value
, param
);
888 virt_build_page (cherokee_handler_virt_t
*hdl
)
891 cherokee_connection_t
*conn
= HANDLER_CONN(hdl
);
892 cherokee_buffer_t uri
= CHEROKEE_BUF_INIT
;
893 cherokee_buffer_t domu
= CHEROKEE_BUF_INIT
;
895 if (hdl
->action
> xml
&& HDL_VIRT_PROPS(hdl
)->xsl
.len
> 0)
896 cherokee_buffer_add_va (&hdl
->buffer
, "<?xml version=\"1.0\"?>\n<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n", HDL_VIRT_PROPS(hdl
)->xsl
.buf
);
899 /* First, block the event loop */
900 avahi_threaded_poll_lock(HDL_AVAHI_PROPS(hdl
)->threaded_poll
);
901 switch (hdl
->action
) {
903 cherokee_buffer_add_str (&hdl
->buffer
, "<domains>");
904 cherokee_avl_while(&HDL_AVAHI_PROPS(hdl
)->entries
, virt_while
, hdl
, NULL
, NULL
);
905 cherokee_buffer_add_str (&hdl
->buffer
, "</domains>");
911 cherokee_buffer_add_str (&hdl
->buffer
, "<domains>");
912 cherokee_avl_while(&HDL_AVAHI_PROPS(hdl
)->entries
, virt_while_user
, hdl
, NULL
, NULL
);
913 cherokee_buffer_add_str (&hdl
->buffer
, "</domains>");
919 cherokee_buffer_t
*hostname
= NULL
;
920 cherokee_buffer_add_va (&domu
, "%s_%s", hdl
->user
.buf
, hdl
->vm
.buf
);
921 ret
= cherokee_avl_get_ptr(&HDL_AVAHI_PROPS(hdl
)->entries
, domu
.buf
, (void **) &hostname
);
923 if (ret
== ret_not_found
) {
925 virConnectPtr virConn
;
926 cherokee_buffer_add_va (&uri
, "xen://%s/", HDL_VIRT_PROPS(hdl
)->virt
); // TODO: change!
928 if (HDL_VIRT_PROPS(hdl
)->read_only
== FALSE
)
929 virConn
= virConnectOpen (uri
.buf
);
931 if (!virConn
&& !(virConn
= virConnectOpenReadOnly (uri
.buf
))) {
932 conn
->error_code
= http_service_unavailable
;
936 if ((virDom
= virDomainLookupByName(virConn
, domu
.buf
)) == NULL
) {
937 if (hdl
->action
!= domainDefineXML_args
&& hdl
->action
!= domainDefineXML
) {
938 hdl
->action
= nothing
;
939 conn
->error_code
= http_not_found
;
945 virDomainFree(virDom
);
948 virConnectClose (virConn
);
949 } else if (ret
== ret_ok
) {
950 cherokee_buffer_add_va (&uri
, "xen://%s/", hostname
->buf
);
951 printf("%s\n", uri
.buf
);
953 hdl
->action
= http_internal_error
;
954 hdl
->action
= nothing
;
960 /* Finally, unblock the event loop */
961 avahi_threaded_poll_unlock(HDL_AVAHI_PROPS(hdl
)->threaded_poll
);
963 if (ret
== ret_ok
&& hdl
->action
!= showall
&& hdl
->action
!= showuservms
) {
964 ret
= virt_virt_do(hdl
, &domu
, &uri
);
967 cherokee_buffer_mrproper(&domu
);
968 cherokee_buffer_mrproper(&uri
);
976 cherokee_handler_virt_new (cherokee_handler_t
**hdl
, cherokee_connection_t
*cnt
, cherokee_module_props_t
*props
)
979 CHEROKEE_NEW_STRUCT (n
, handler_virt
);
981 /* Init the base class
984 cherokee_handler_init_base(HANDLER(n
), cnt
, HANDLER_PROPS(props
), PLUGIN_INFO_HANDLER_PTR(virt
));
986 MODULE(n
)->init
= (handler_func_init_t
) cherokee_handler_virt_init
;
987 MODULE(n
)->free
= (module_func_free_t
) cherokee_handler_virt_free
;
988 HANDLER(n
)->step
= (handler_func_step_t
) cherokee_handler_virt_step
;
989 HANDLER(n
)->add_headers
= (handler_func_add_headers_t
) cherokee_handler_virt_add_headers
;
991 HANDLER(n
)->support
= hsupport_length
| hsupport_range
;
993 ret
= cherokee_buffer_init (&n
->buffer
);
994 if (unlikely(ret
!= ret_ok
))
997 ret
= cherokee_buffer_ensure_size (&n
->buffer
, 4*1024);
998 if (unlikely(ret
!= ret_ok
))