Mercurial > hg > Applications > virsh-wrapper
view ie-virsh.c @ 50:7a02dee972c4
easy fix randomUUID
author | kono |
---|---|
date | Tue, 30 Jan 2018 22:13:22 +0900 |
parents | b8887c40f8b8 |
children | e45676e6b6cd |
line wrap: on
line source
#include <stdlib.h> #include <unistd.h> #include <stdbool.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <regex.h> #include <pwd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <time.h> /* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */ #define command "/usr/bin/virsh" /* #define command "/usr/local/bin/virsh" */ #define list_command "/usr/bin/virsh list --all" /* #define list_command "/usr/local/bin/virsh list --all" */ #define start_command "start" #define stop_command "destroy" #define define_command "define" #define undefine_command "undefine" #define dumpxml_command "dumpxml" #define console_command "console" #define debug_command "debug" #define define_gdb_command "define-gdb" const char *guests[] = {"145165B"}; const char *managers[] = {"atton"}; const char *students_identifier = "student"; const char *teachers_identifier = "teacher"; const char *students_sym = "students"; const char *teachers_sym = "teachers"; const char *managers_sym = "managers"; const char *guests_sym = "guests"; const char *delimiter = "_"; static char bad_name[] = "Bad vmname. Try 01 or 02 ... 04\n"; const char newvm_command[] = "/usr/local/bin/newvm.py -c /etc/libvirt/qemu/ie-virsh-template.xml -n "; enum { NAME_LENGTH = 50, VM_NAME_LENGTH = 50 }; enum { STUDENTS, GUESTS, MANAGERS, TEACHERS }; #define VMNAME_MAX (512) typedef struct vmlist { char name[VMNAME_MAX]; struct vmlist *next; } VMLIST, *VMLISTPTR; #define NEW(type) ((type*)malloc(sizeof(type))) /* Define global variables */ VMLISTPTR get_vmlist(char *list_pattern_str) { regex_t *list_pattern = NEW(regex_t); if (regcomp(list_pattern, list_pattern_str, 0) != 0) { exit(0); } VMLISTPTR list = NEW(VMLIST); VMLISTPTR p = list ; p->name[0] = 0; p->next = 0; FILE *fp = popen(list_command,"r"); while(fgets(p->name,VMNAME_MAX,fp)!=NULL) { if (regexec(list_pattern, p->name, (size_t) 0, NULL, 0)) continue; p->next = NEW(VMLIST); p = p->next; } p->name[0] = 0; pclose(fp); regfree(list_pattern); return list; } void print_vmlist(VMLISTPTR list) { for(;list && list->name[0]; list=list->next) { fprintf(stdout, " %s\n",list->name); } } void check_vmlist_name(VMLISTPTR list, char * name) { for(;list && list->name[0]; list=list->next) { if (strstr(list->name, name)!=0) return; } fprintf(stderr, bad_name); print_vmlist(list); exit(1); } void change_delimiter_to_slash(char *name) { long size = sizeof(char) * VM_NAME_LENGTH; int i = 0; for (; i < size; i++) { if (name[i] == '_') { name[i] = '/'; } } } int check_name(const char *p) { if (!p) return 1; for(;*p;p++) { char c = *p; if (c<=' ') return 1; if (('a'<=c && c<='z') || ('0'<=c && c<='9') || ('/'==c ) || ('-'==c )) continue; return 1; printf("%c", c); } return 0; } void usage() { printf("Usage: COMMAND [define|define-gdb|list|start|destroy|dumpxml|vncdisplay|undefine|console] [vm-name]\n"); printf(" vm-name should be 01 - 04\n"); } int check_user_name(const char *account_name) { const char *home = getpwuid(getuid())->pw_dir; if (strstr(home, students_identifier) != NULL) { return STUDENTS; } else if (strstr(home, teachers_identifier) != NULL) { return TEACHERS; } const int managers_num = sizeof(managers) / sizeof(managers[0]); int i = 0; for (; i < managers_num; i++) { if (strncmp(account_name, managers[i], NAME_LENGTH) == 0) { return MANAGERS; } } const int guests_num = sizeof(guests) / sizeof(guests[0]); int j = 0; for (; j < guests_num; j++) { if (strncmp(account_name, guests[j], NAME_LENGTH) == 0) { return GUESTS; } } return -1; } void bind_name(char *name, const char *first, const char *second) { strncat(name, first, VM_NAME_LENGTH); strncat(name, delimiter, VM_NAME_LENGTH); strncat(name, second, VM_NAME_LENGTH); strncat(name, delimiter, VM_NAME_LENGTH); return; } void make_vm_name(char *vm_name, const int account_type, const char *account_name, const char *vm_num) { const char *regex = "0[1-4]"; regex_t *num_pattern = NEW(regex_t); if (regcomp(num_pattern, regex, REG_EXTENDED|REG_NEWLINE) != 0) { exit(0); } int ret = regexec(num_pattern, vm_num, (size_t) 0, NULL, 0); regfree(num_pattern); if (ret){ fprintf(stderr, "This name is invalid number: %s\n", vm_num); exit(0); } switch(account_type) { case STUDENTS: strncat(vm_name, students_sym, VM_NAME_LENGTH); strncat(vm_name, delimiter, VM_NAME_LENGTH); strncat(vm_name, account_name, 3); strncat(vm_name, delimiter, VM_NAME_LENGTH); strncat(vm_name, account_name, VM_NAME_LENGTH); strncat(vm_name, delimiter, VM_NAME_LENGTH); break; case TEACHERS: strncat(vm_name, teachers_sym, VM_NAME_LENGTH); strncat(vm_name, delimiter, VM_NAME_LENGTH); strncat(vm_name, account_name, VM_NAME_LENGTH); strncat(vm_name, delimiter, VM_NAME_LENGTH); break; case GUESTS: bind_name(vm_name, guests_sym, account_name); break; case MANAGERS: bind_name(vm_name, managers_sym, account_name); break; default : fprintf(stderr, "Error: no registered type name."); return; } strncat(vm_name, vm_num, VM_NAME_LENGTH); } int get_kernel_debug_port(void){ struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); int socket_fd = socket(AF_INET, SOCK_STREAM, 0); int i; srand(time(NULL)); for (i = 0; i < 10; i++) { addr.sin_port = htons((rand() % 20000) + 10000); if ((bind(socket_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr) ) == 0) && (listen(socket_fd, 1) == 0)) { printf("Port %d was allocated for your kernel debug.\n", ntohs(addr.sin_port)); close(socket_fd); return ntohs(addr.sin_port); } else { printf("Port %d was used. Trying another port...\n", ntohs(addr.sin_port)); } } printf("Cannot allocate debug port.\n"); exit(EXIT_FAILURE); } void create_new_vm(const char const *name, const char const *vm_name, char* xml_name, bool debug_kernel){ if (check_name(name)) { fprintf(stderr, bad_name); exit(0); } char *vm_path = (char *)malloc(sizeof(char) * VM_NAME_LENGTH); strncpy(vm_path, vm_name, VM_NAME_LENGTH); change_delimiter_to_slash(vm_path); char exec[1024]; if (debug_kernel) { snprintf(exec, 1024, "%s %s -d %d", newvm_command, vm_path, get_kernel_debug_port()); } else { snprintf(exec, 1024, "%s %s", newvm_command, vm_path); } fprintf(stdout, "excuting %s\n",exec ); system(exec); strncpy(xml_name, vm_path,900); strncat(xml_name,".xml",1000); free(vm_path); } /* main(int argc, char **argv) - main process loop */ int main(int argc, char **argv) { /* Set euid and egid to actual user */ int uid = getuid(); int gid = getgid(); char *name = getlogin(); printf("uid %d gid %d name %s\n", uid,gid,name); setegid(getgid()); seteuid(getuid()); int account_type = check_user_name(name); if (account_type < 0) { fprintf(stderr, "Parmission denied. :%s\n", name); exit(1); } /* Confirm user is in GROUP(999) group */ /* if ( gid != 999 ) { printf("User Not Authorized! Exiting...\n"); exit(1); } */ if (argc<2) { usage(); exit(0); } /* Set uid, gid, euid and egid to root */ setegid(0); seteuid(0); setgid(0); setuid(0); char *vm_name = (char *)malloc(sizeof(char) * VM_NAME_LENGTH); vm_name[0] = '\0'; if ((argc > 2) && (strncmp(argv[1], list_command, 4) != 0)) { make_vm_name(vm_name, account_type, name, argv[2]); } VMLISTPTR vmlist = get_vmlist(name); /* Check argv for proper arguments and run * the corresponding script, if invoked. */ if (argv[1]==0 || strncmp(argv[1], "list", 4) == 0 ) { print_vmlist(vmlist); } else if (strncmp(argv[1], start_command, 5) == 0) { if (argc<3) {usage(); exit(1);} check_vmlist_name(vmlist, argv[2]); if (execl(command, command, start_command, vm_name, NULL) < 0) { perror("Execl:"); } } else if ( strncmp(argv[1], stop_command, 4) == 0 ) { if (argc<3) {usage(); exit(1);} check_vmlist_name(vmlist, argv[2]); if (execl(command, command, stop_command, vm_name, NULL) < 0) { perror("Execl:"); } } else if ( strncmp(argv[1], dumpxml_command, 7) == 0 ) { if (argc<3) {usage(); exit(1);} check_vmlist_name(vmlist, argv[2]); if (execl(command, command, dumpxml_command, vm_name, NULL) < 0) { perror("Execl:"); } } else if ( strncmp(argv[1], "vncdisplay", 10) == 0 ) { if (argc<3) {usage(); exit(1);} check_vmlist_name(vmlist, argv[2]); if (execl(command, command, "vncdisplay", vm_name, NULL) < 0) { perror("Execl:"); } } else if ( strncmp(argv[1], console_command, 8) == 0 ) { if (argc<3) {usage(); exit(1);} check_vmlist_name(vmlist, argv[2]); if (execl(command, command, console_command, vm_name, NULL) < 0) { perror("Execl:"); } } else if (strcmp(argv[1], define_command) == 0 ) { if (argc<3) {usage(); exit(1);} char xml_name[1024]; xml_name[0] = 0; create_new_vm(argv[2], vm_name, xml_name, false); /* chdir("/usr/local/etc/libvirt/qemu"); */ chdir("/etc/libvirt/qemu"); if (execl(command, command, define_command, xml_name, NULL) < 0) { perror("Execl:"); } } else if (strcmp(argv[1], define_gdb_command) == 0 ) { if (argc<3) {usage(); exit(1);} char xml_name[1024]; xml_name[0] = 0; create_new_vm(argv[2], vm_name, xml_name, true); /* chdir("/usr/local/etc/libvirt/qemu"); */ chdir("/etc/libvirt/qemu"); if (execl(command, command, define_command, xml_name, NULL) < 0) { perror("Execl:"); } } else if ( strncmp(argv[1], undefine_command, 8) == 0 ) { /* chdir("/usr/local/etc/libvirt/qemu"); */ chdir("/etc/libvirt/qemu"); if (execl(command, command, undefine_command, vm_name, NULL) < 0) { perror("Execl:"); } } else { printf("%s is invalid command.\n", argv[1]); usage(); exit(1); } free(vm_name); exit(0); } /* end */