basic C program to interact with API for listing VMs
This commit is contained in:
parent
943a1218ec
commit
e11b7e85e2
|
@ -0,0 +1,286 @@
|
|||
#include <libvirt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void pr_bad();
|
||||
void pr_conn_bad();
|
||||
void pr_conn_good();
|
||||
void pr_fatal_and_exit(int e);
|
||||
void pr_good();
|
||||
void pr_no_match();
|
||||
|
||||
int get_domain(char *uuid, virDomainPtr *domain);
|
||||
char * get_state_string(virDomainPtr dom, int state);
|
||||
|
||||
void lv_get_name(char *uuid);
|
||||
void lv_get_state(char *uuid);
|
||||
void lv_get_xml(char *uuid);
|
||||
void lv_list_all_name();
|
||||
void lv_list_all_uuid();
|
||||
|
||||
const int E_LIBVIRT=16;
|
||||
virConnectPtr conn;
|
||||
|
||||
/*One of these is displayed on startup. If CONN_BAD, program exits*/
|
||||
const char CONN_BAD[]= "# No Connection";
|
||||
const char CONN_GOOD[]="# Connected";
|
||||
|
||||
/*After a command is issued, one of these displays. Only GOOD is followed
|
||||
by the requested information */
|
||||
const char BAD_REQ[]="# Bad Request";
|
||||
const char FATAL[]= "# Fatal error";
|
||||
const char GOOD[]= "# Making API Request";
|
||||
const char NOMATCH[]="# No matching domain";
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* Possible commands:
|
||||
* list: list UUIDs of all domains that are defined and/or running
|
||||
* list_name: list names of all domains that are defined and/or running
|
||||
* get_name <uuid>: get name of domain
|
||||
* get_state <uuid>: get state of domain as defined in man qq2clone. It
|
||||
* is possible, though unlikely for this to return an empty string
|
||||
* even when referring to a valid uuid
|
||||
* get_xml <uuid>: print xml file describing domain (prints current
|
||||
* config of a running machine, rather than inactive config)
|
||||
*/
|
||||
|
||||
int main () {
|
||||
/* Connect to libvirt API */
|
||||
conn=virConnectOpen(NULL);
|
||||
int loop=1;
|
||||
if ( conn == NULL) {
|
||||
pr_conn_bad();
|
||||
exit(E_LIBVIRT);
|
||||
} else {
|
||||
pr_conn_good();
|
||||
}
|
||||
|
||||
char *lineptr, *token, **str_arr;
|
||||
const char delim[]="\t\n ";
|
||||
unsigned int count;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
/* Get input from stdin and execute commands in a loop */
|
||||
while(1) {
|
||||
str_arr=NULL;
|
||||
lineptr=NULL; n=0; count=0;
|
||||
|
||||
getline(&lineptr,&n,stdin);
|
||||
token=strtok(lineptr,delim);
|
||||
if (token == NULL) { free(lineptr); pr_bad(); continue; }
|
||||
|
||||
while (token != NULL) {
|
||||
str_arr=realloc(str_arr, sizeof(char*) * (count + 1) );
|
||||
if (str_arr == NULL){ pr_fatal_and_exit(1); }
|
||||
str_arr[count]=token;
|
||||
count++;
|
||||
token=strtok(NULL,delim);
|
||||
}
|
||||
|
||||
if ( count > 2 || count == 0) { free(lineptr); pr_bad(); continue; }
|
||||
if ( strcmp( str_arr[0], "exit" ) == 0 ) {
|
||||
virConnectClose(conn); exit(0);
|
||||
|
||||
} else if (strcmp( str_arr[0], "list" ) == 0 ) {
|
||||
if (count==1){ lv_list_all_uuid(); } else { pr_bad(); }
|
||||
|
||||
} else if (strcmp( str_arr[0], "list_name" ) == 0 ) {
|
||||
if (count==1){ lv_list_all_name(); } else { pr_bad(); }
|
||||
|
||||
} else if (strcmp( str_arr[0], "get_name" ) == 0 ) {
|
||||
if (count==2){ lv_get_name(str_arr[1]); } else { pr_bad(); }
|
||||
|
||||
} else if (strcmp( str_arr[0], "get_state" ) == 0 ) {
|
||||
if (count==2){ lv_get_state(str_arr[1]); } else { pr_bad(); }
|
||||
|
||||
} else if (strcmp( str_arr[0], "get_xml" ) == 0 ) {
|
||||
if (count==2){ lv_get_xml(str_arr[1]); } else { pr_bad(); }
|
||||
|
||||
} else {
|
||||
pr_bad();
|
||||
}
|
||||
|
||||
free(lineptr);
|
||||
if (str_arr != NULL){ free(str_arr); }
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/***********************************
|
||||
* Basic, repeated output sequences *
|
||||
***********************************/
|
||||
|
||||
void pr_bad() {
|
||||
printf("+%s\n",BAD_REQ);
|
||||
}
|
||||
|
||||
void pr_conn_bad() {
|
||||
printf("+%s\n", CONN_BAD);
|
||||
}
|
||||
|
||||
void pr_conn_good() {
|
||||
printf("+%s\n",CONN_GOOD);
|
||||
}
|
||||
|
||||
/* Okay, this one provides a basic output sequence *and* quits */
|
||||
void pr_fatal_and_exit(int e) {
|
||||
printf("+%s\n",FATAL);
|
||||
virConnectClose;
|
||||
exit(e);
|
||||
}
|
||||
|
||||
void pr_good() {
|
||||
printf("+%s\n",GOOD);
|
||||
}
|
||||
|
||||
void pr_no_match() {
|
||||
printf("+%s\n",NOMATCH);
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Helper functions for working with API *
|
||||
*****************************************/
|
||||
|
||||
int get_domain(char *uuid, virDomainPtr *domain){
|
||||
*domain=virDomainLookupByUUIDString(conn, (const char *) uuid);
|
||||
if (domain == NULL){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * get_state_string(virDomainPtr dom, int state)
|
||||
{
|
||||
if (state == VIR_DOMAIN_RUNNING) {
|
||||
return ("running");
|
||||
} else if (state == VIR_DOMAIN_BLOCKED) {
|
||||
return ("idle");
|
||||
} else if ( state == VIR_DOMAIN_PAUSED ) {
|
||||
return ("paused");
|
||||
} else if ( state == VIR_DOMAIN_SHUTDOWN ) {
|
||||
return("shutting-down");
|
||||
} else if ( state == VIR_DOMAIN_SHUTOFF ) {
|
||||
int saved;
|
||||
saved=virDomainHasManagedSaveImage(dom,0);
|
||||
if( saved == 1 ) {
|
||||
return("saved");
|
||||
} else if ( saved == 0 ) {
|
||||
return("off");
|
||||
} else {
|
||||
return(NULL);
|
||||
}
|
||||
} else if ( state == VIR_DOMAIN_CRASHED ) {
|
||||
return("crashed");
|
||||
} else if ( state == VIR_DOMAIN_PMSUSPENDED ) {
|
||||
return ("pmsuspended");
|
||||
} else {
|
||||
return("");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* Get information from libvirt API and print to stdout *
|
||||
*******************************************************/
|
||||
|
||||
void lv_get_name (char *uuid){
|
||||
virDomainPtr domain;
|
||||
if (get_domain(uuid, &domain) == 0){
|
||||
pr_good();
|
||||
const char *name;
|
||||
name=virDomainGetName(domain);
|
||||
if (name!=NULL){ printf("+%s\n",name); }
|
||||
else { pr_fatal_and_exit(E_LIBVIRT); }
|
||||
virDomainFree(domain);
|
||||
}else{
|
||||
pr_no_match();
|
||||
}
|
||||
}
|
||||
|
||||
void lv_get_state(char *uuid){
|
||||
virDomainPtr domain;
|
||||
if (get_domain(uuid, &domain) == 0){
|
||||
pr_good();
|
||||
int *state=malloc(sizeof(state)), *reason=malloc(sizeof(reason)), ret;
|
||||
ret=virDomainGetState(domain,state,reason,0);
|
||||
if ( ret==0 ){
|
||||
const char *state_str;
|
||||
state_str=get_state_string(domain, *state);
|
||||
printf("+%s\n",state_str);
|
||||
} else { printf("+\n"); }
|
||||
virDomainFree(domain);
|
||||
free(state);
|
||||
free(reason);
|
||||
}else{
|
||||
pr_no_match();
|
||||
}
|
||||
}
|
||||
|
||||
void lv_get_xml(char *uuid){
|
||||
virDomainPtr domain;
|
||||
if (get_domain(uuid, &domain) == 0){
|
||||
pr_good();
|
||||
char *xml;
|
||||
xml=virDomainGetXMLDesc(domain, 0);
|
||||
if ( xml!=NULL ){
|
||||
|
||||
char *token;
|
||||
token=strtok(xml, "\n");
|
||||
if(token==NULL) { free(xml); virDomainFree(domain); return; }
|
||||
|
||||
while (token != NULL) {
|
||||
printf ("+%s\n",token);
|
||||
token=strtok(NULL, "\n");
|
||||
}
|
||||
free(xml);
|
||||
}
|
||||
else { pr_fatal_and_exit(E_LIBVIRT); }
|
||||
virDomainFree(domain);
|
||||
}else{
|
||||
pr_no_match();
|
||||
}
|
||||
}
|
||||
|
||||
void lv_list_all_uuid() {
|
||||
virDomainPtr *domains;
|
||||
int ret_list, ret_uuid, i;
|
||||
ret_list=virConnectListAllDomains(conn,&domains,0);
|
||||
if(ret_list<0){ virConnectClose(conn);
|
||||
pr_fatal_and_exit(E_LIBVIRT); };
|
||||
pr_good();
|
||||
|
||||
char *uuid=malloc(VIR_UUID_STRING_BUFLEN);
|
||||
for(i=0;i<ret_list;i++){
|
||||
ret_uuid=virDomainGetUUIDString(domains[i],uuid);
|
||||
if (ret_uuid==0) {
|
||||
printf("+%s\n",uuid);
|
||||
virDomainFree(domains[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(uuid);
|
||||
free(domains);
|
||||
}
|
||||
|
||||
void lv_list_all_name() {
|
||||
virDomainPtr *domains;
|
||||
int ret_list, i;
|
||||
ret_list=virConnectListAllDomains(conn,&domains,0);
|
||||
if(ret_list<0){ virConnectClose(conn); pr_fatal_and_exit(E_LIBVIRT); };
|
||||
pr_good();
|
||||
|
||||
const char *name;
|
||||
for(i=0;i<ret_list;i++){
|
||||
name=virDomainGetName(domains[i]);
|
||||
if (name!=NULL){ printf("+%s\n",name); }
|
||||
else { pr_fatal_and_exit(E_LIBVIRT); }
|
||||
virDomainFree(domains[i]);
|
||||
}
|
||||
|
||||
free(domains);
|
||||
}
|
Loading…
Reference in New Issue