Преглед изворни кода

实现虚拟机开机启动

James Iter пре 7 година
родитељ
комит
effd8d86b2

+ 52 - 0
jimvc/api/guest.py

@@ -92,6 +92,11 @@ def r_create():
             Rules.SERVICE_ID.value
             Rules.SERVICE_ID.value
         )
         )
 
 
+    if 'autostart' in request.json:
+        args_rules.append(
+            Rules.AUTOSTART.value
+        )
+
     try:
     try:
         ret = dict()
         ret = dict()
         ret['state'] = ji.Common.exchange_state(20000)
         ret['state'] = ji.Common.exchange_state(20000)
@@ -220,6 +225,7 @@ def r_create():
             guest.os_template_image_id = request.json.get('os_template_image_id')
             guest.os_template_image_id = request.json.get('os_template_image_id')
             guest.label = ji.Common.generate_random_code(length=8)
             guest.label = ji.Common.generate_random_code(length=8)
             guest.remark = request.json.get('remark', '')
             guest.remark = request.json.get('remark', '')
+            guest.autostart = request.json.get('autostart', False)
 
 
             guest.password = request.json.get('password')
             guest.password = request.json.get('password')
             if guest.password is None or guest.password.__len__() < 1:
             if guest.password is None or guest.password.__len__() < 1:
@@ -300,6 +306,7 @@ def r_create():
                 'storage_mode': config.storage_mode,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
                 'dfs_volume': config.dfs_volume,
                 'node_id': guest.node_id,
                 'node_id': guest.node_id,
+                'autostart': guest.autostart,
                 'name': guest.label,
                 'name': guest.label,
                 'template_path': os_template_image.path,
                 'template_path': os_template_image.path,
                 'os_type': os_template_profile.os_type,
                 'os_type': os_template_profile.os_type,
@@ -317,6 +324,51 @@ def r_create():
         return json.loads(e.message)
         return json.loads(e.message)
 
 
 
 
+@Utils.dumps2response
+def r_autostart(uuids, autostart):
+
+    args_rules = [
+        Rules.UUIDS.value,
+        Rules.AUTOSTART.value
+    ]
+
+    if str(autostart).lower() in ['false', '0']:
+        autostart = False
+
+    else:
+        autostart = True
+
+    try:
+        ji.Check.previewing(args_rules, {'uuids': uuids, 'autostart': autostart})
+
+        guest = Guest()
+        for uuid in uuids.split(','):
+            guest.uuid = uuid
+            guest.get_by('uuid')
+
+        for uuid in uuids.split(','):
+            guest.uuid = uuid
+            guest.get_by('uuid')
+
+            message = {
+                '_object': 'guest',
+                'action': 'autostart',
+                'uuid': uuid,
+                'node_id': guest.node_id,
+                'autostart': autostart,
+                'passback_parameters': {'autostart': autostart}
+            }
+
+            Utils.emit_instruction(message=json.dumps(message))
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        return ret
+
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+
+
 @Utils.dumps2response
 @Utils.dumps2response
 def r_reboot(uuids):
 def r_reboot(uuids):
 
 

+ 1 - 0
jimvc/api_route_table.py

@@ -120,6 +120,7 @@ add_rule_api(os_template_initialize_operate.blueprints, '/_search',
 # Guest操作
 # Guest操作
 # 创建虚拟机
 # 创建虚拟机
 add_rule_api(guest.blueprint, '', api_func='guest.r_create', methods=['POST'])
 add_rule_api(guest.blueprint, '', api_func='guest.r_create', methods=['POST'])
+add_rule_api(guest.blueprints, '/_autostart/<uuids>/<autostart>', api_func='guest.r_autostart', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_reboot/<uuids>', api_func='guest.r_reboot', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_reboot/<uuids>', api_func='guest.r_reboot', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_force_reboot/<uuids>', api_func='guest.r_force_reboot', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_force_reboot/<uuids>', api_func='guest.r_force_reboot', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_shutdown/<uuids>', api_func='guest.r_shutdown', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_shutdown/<uuids>', api_func='guest.r_shutdown', methods=['PUT'])

+ 7 - 0
jimvc/models/event_processor.py

@@ -208,6 +208,13 @@ class EventProcessor(object):
                     cls.guest.password = cls.message['message']['passback_parameters']['password']
                     cls.guest.password = cls.message['message']['passback_parameters']['password']
                     cls.guest.update()
                     cls.guest.update()
 
 
+            elif action == 'autostart':
+                if state == ResponseState.success.value:
+                    cls.guest.uuid = uuid
+                    cls.guest.get_by('uuid')
+                    cls.guest.autostart = cls.message['message']['passback_parameters']['autostart']
+                    cls.guest.update()
+
             elif action == 'attach_disk':
             elif action == 'attach_disk':
                 cls.disk.uuid = cls.message['message']['passback_parameters']['disk_uuid']
                 cls.disk.uuid = cls.message['message']['passback_parameters']['disk_uuid']
                 cls.disk.get_by('uuid')
                 cls.disk.get_by('uuid')

+ 5 - 2
jimvc/models/guest.py

@@ -25,6 +25,7 @@ class Guest(ORM):
         self.id = 0
         self.id = 0
         self.uuid = None
         self.uuid = None
         self.label = None
         self.label = None
+        self.autostart = False
         self.password = None
         self.password = None
         self.remark = ''
         self.remark = ''
         self.os_template_image_id = None
         self.os_template_image_id = None
@@ -49,6 +50,7 @@ class Guest(ORM):
             'id': FilterFieldType.INT.value,
             'id': FilterFieldType.INT.value,
             'uuid': FilterFieldType.STR.value,
             'uuid': FilterFieldType.STR.value,
             'label': FilterFieldType.STR.value,
             'label': FilterFieldType.STR.value,
+            'autostart': FilterFieldType.BOOL.value,
             'status': FilterFieldType.INT.value,
             'status': FilterFieldType.INT.value,
             'remark': FilterFieldType.STR.value,
             'remark': FilterFieldType.STR.value,
             'node_id': FilterFieldType.INT.value,
             'node_id': FilterFieldType.INT.value,
@@ -59,11 +61,12 @@ class Guest(ORM):
 
 
     @staticmethod
     @staticmethod
     def get_allow_update_keywords():
     def get_allow_update_keywords():
-        return ['remark', 'cpu', 'memory', 'bandwidth', 'network', 'manage_network', 'vnc_password', 'service_id']
+        return ['autostart','remark', 'cpu', 'memory', 'bandwidth', 'network', 'manage_network', 'vnc_password',
+                'service_id']
 
 
     @staticmethod
     @staticmethod
     def get_allow_content_search_keywords():
     def get_allow_content_search_keywords():
-        return ['label', 'remark', 'node_id', 'ip']
+        return ['label', 'autostart', 'remark', 'node_id', 'ip']
 
 
 
 
 class Disk(ORM):
 class Disk(ORM):

+ 1 - 0
jimvc/models/rules.py

@@ -71,6 +71,7 @@ class Rules(Enum):
     UUID = (basestring, 'uuid', (36, 36))
     UUID = (basestring, 'uuid', (36, 36))
     NODE_ID = (basestring, 'node_id', (16, 16))
     NODE_ID = (basestring, 'node_id', (16, 16))
     UUIDS = (REG_UUIDS, 'uuids')
     UUIDS = (REG_UUIDS, 'uuids')
+    AUTOSTART = (int, 'autostart')
     CPU = (int, 'cpu')
     CPU = (int, 'cpu')
     MEMORY = (int, 'memory')
     MEMORY = (int, 'memory')
     OS_TEMPLATE_IMAGE_ID = (int, 'os_template_image_id')
     OS_TEMPLATE_IMAGE_ID = (int, 'os_template_image_id')

+ 89 - 2
jimvc/themes/default/templates/guests_show.html

@@ -611,6 +611,23 @@
         shortcut_bar_enable();
         shortcut_bar_enable();
     }
     }
 
 
+    function autostart(uuids, autostart) {
+        $.ajax({
+            url : '/api/guests/_autostart/' + uuids.join(',') + '/' + autostart,
+            type : 'PUT',
+            contentType: "application/json; charset=utf-8",
+            error : function() {
+                alter_danger('实例变更启动方式指令发送失败!');
+            },
+            success : function() {
+                alter_success('实例变更启动方式指令发送成功!');
+                setTimeout(function() {
+                    window.location.reload();
+                }, 1000);
+            }
+        });
+    }
+
     function boot(uuids) {
     function boot(uuids) {
         $.ajax({
         $.ajax({
             url : '/api/guests/_boot/' + uuids.join(','),
             url : '/api/guests/_boot/' + uuids.join(','),
@@ -918,6 +935,16 @@
         $('#resume_modal').modal('hide');
         $('#resume_modal').modal('hide');
     }
     }
 
 
+    function autostart_at(me) {
+        var _autostart = 0;
+
+        if ($(me).data('autostart') === 0) {
+            _autostart = 1;
+        }
+        var uuid = $(me).parent().parent().children()[0].textContent;
+        autostart([uuid], _autostart);
+    }
+
     function allocate_bandwidth_at(me) {
     function allocate_bandwidth_at(me) {
         var uuid = $('#instance_uuid').val();
         var uuid = $('#instance_uuid').val();
         allocate_bandwidth([uuid], $('#bandwidth').val(), $('#bandwidth_unit').val());
         allocate_bandwidth([uuid], $('#bandwidth').val(), $('#bandwidth_unit').val());
@@ -1087,6 +1114,22 @@
         $('#batch_resume_modal').modal('hide');
         $('#batch_resume_modal').modal('hide');
     }
     }
 
 
+    function batch_autostart() {
+        var uuids = get_checked_uuids();
+        if (uuids) {
+            autostart(uuids, 1);
+        }
+        $('#batch_autostart_modal').modal('hide');
+    }
+
+    function batch_disable_autostart() {
+        var uuids = get_checked_uuids();
+        if (uuids) {
+            autostart(uuids, 0);
+        }
+        $('#batch_disable_autostart_modal').modal('hide');
+    }
+
     function batch_allocate_bandwidth() {
     function batch_allocate_bandwidth() {
         var uuids = get_checked_uuids();
         var uuids = get_checked_uuids();
         if (uuids) {
         if (uuids) {
@@ -1286,6 +1329,7 @@
                 '<td width="40px" style="padding-left: 12px;">' +
                 '<td width="40px" style="padding-left: 12px;">' +
                     '<span class="' + guest.html.logo + '" title="' + guest.html.os_template_label + '"></span>' +
                     '<span class="' + guest.html.logo + '" title="' + guest.html.os_template_label + '"></span>' +
                 '</td>' +
                 '</td>' +
+                '<td><a data-autostart="' + guest.autostart + '" class="icon-os icon-autostart" title="' + (function () { if (guest.autostart !== 0) { return '切至手动启动'; } else { return '切至开机启动';}})() + '" href="javascript:;" onclick="autostart_at(this);" style="' + (function () { if (guest.autostart === 0) { return 'filter: grayscale(100%);'; } else { return '';}})() + '"></a></td>' +
                 '<td>' + guest.html.status + '</td>' +
                 '<td>' + guest.html.status + '</td>' +
                 '<td>' + guest.hostname + '</td>' +
                 '<td>' + guest.hostname + '</td>' +
                 '<td>' +
                 '<td>' +
@@ -1680,8 +1724,7 @@
                         {% endif %}
                         {% endif %}
                     </td>
                     </td>
                     <td>
                     <td>
-                        <span class="icon-os icon-autostart" title="随机启动"></span>
-                        <!--<img width="16px" height="16px" src="{{ theme_static('images/icons/onboot.png') }}"></img>-->
+                        <a data-autostart="{{ item.autostart }}" class="icon-os icon-autostart" title="{% if item.autostart != 0 %}切至手动启动{% else %}切至开机启动{% endif %}" href="javascript:;" onclick="autostart_at(this);" style="{% if item.autostart == 0 %}filter: grayscale(100%);{% endif %}"></a>
                     </td>
                     </td>
                     <td>{{ format_guest_status(item.status, item.progress)|safe }}</td>
                     <td>{{ format_guest_status(item.status, item.progress)|safe }}</td>
                     <td>{{ hosts_mapping_by_node_id[item.node_id | string].hostname }}</td>
                     <td>{{ hosts_mapping_by_node_id[item.node_id | string].hostname }}</td>
@@ -1883,6 +1926,12 @@
                                                 </ul>
                                                 </ul>
                                             </li>
                                             </li>
                                             <li class="divider"></li>
                                             <li class="divider"></li>
+                                            <li>
+                                                <a href="javascript:;" data-toggle="modal" data-target="#batch_autostart_modal">开机启动</a>
+                                            </li>
+                                            <li>
+                                                <a href="javascript:;" data-toggle="modal" data-target="#batch_disable_autostart_modal">手动启动</a>
+                                            </li>
                                             <li>
                                             <li>
                                                 <a href="javascript:;" data-toggle="modal" data-target="#batch_allocate_bandwidth_modal">分配带宽</a>
                                                 <a href="javascript:;" data-toggle="modal" data-target="#batch_allocate_bandwidth_modal">分配带宽</a>
                                             </li>
                                             </li>
@@ -2748,4 +2797,42 @@
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
+
+<div class="modal" id="batch_autostart_modal" tabindex="-1" role="dialog" style="margin-top: 100px;">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 class="modal-title">批量使虚拟机开机启动:</h4>
+            </div>
+            <div class="modal-body">
+                <p></p>
+                <p>您确定要使选定的虚拟机开机启动吗?</p>
+                <p></p>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-primary" onclick="batch_autostart();">确定</button>
+                <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div class="modal" id="batch_disable_autostart_modal" tabindex="-1" role="dialog" style="margin-top: 100px;">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 class="modal-title">批量取消虚拟机开机启动:</h4>
+            </div>
+            <div class="modal-body">
+                <p></p>
+                <p>您确定要使选定的虚拟机取消开机启动吗?</p>
+                <p></p>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-primary" onclick="batch_disable_autostart();">确定</button>
+                <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
 {% endblock content %}
 {% endblock content %}

+ 2 - 0
misc/init.sql

@@ -32,6 +32,7 @@ CREATE TABLE IF NOT EXISTS guest(
     label VARCHAR(64) NOT NULL UNIQUE,
     label VARCHAR(64) NOT NULL UNIQUE,
     password VARCHAR(255) NOT NULL,
     password VARCHAR(255) NOT NULL,
     remark VARCHAR(255) NOT NULL DEFAULT '',
     remark VARCHAR(255) NOT NULL DEFAULT '',
+    autostart BOOLEAN NOT NULL DEFAULT FALSE,
     os_template_image_id BIGINT UNSIGNED NOT NULL,
     os_template_image_id BIGINT UNSIGNED NOT NULL,
     create_time BIGINT UNSIGNED NOT NULL,
     create_time BIGINT UNSIGNED NOT NULL,
     -- 运行时的状态用 status;
     -- 运行时的状态用 status;
@@ -56,6 +57,7 @@ CREATE TABLE IF NOT EXISTS guest(
 
 
 ALTER TABLE guest ADD INDEX (uuid);
 ALTER TABLE guest ADD INDEX (uuid);
 ALTER TABLE guest ADD INDEX (label);
 ALTER TABLE guest ADD INDEX (label);
+ALTER TABLE guest ADD INDEX (autostart);
 ALTER TABLE guest ADD INDEX (node_id);
 ALTER TABLE guest ADD INDEX (node_id);
 ALTER TABLE guest ADD INDEX (service_id);
 ALTER TABLE guest ADD INDEX (service_id);
 ALTER TABLE guest ADD INDEX (ip);
 ALTER TABLE guest ADD INDEX (ip);

+ 3 - 0
misc/v0.7_to_v0.8/update.sql

@@ -41,3 +41,6 @@ CREATE TABLE IF NOT EXISTS reserved_ip(
     DEFAULT CHARSET=utf8;
     DEFAULT CHARSET=utf8;
 
 
 ALTER TABLE reserved_ip ADD INDEX (ip);
 ALTER TABLE reserved_ip ADD INDEX (ip);
+
+ALTER TABLE guest ADD COLUMN autostart BOOLEAN NOT NULL DEFAULT FALSE ;
+ALTER TABLE guest ADD INDEX (autostart);

+ 2 - 0
misc/v0.7_to_v0.8/upgrade.sh

@@ -4,6 +4,8 @@ systemctl stop jimvn
 systemctl stop jimvc
 systemctl stop jimvc
 
 
 deactivate
 deactivate
+sed -i '/\/usr\/local\/venv-jimv\/bin\/activate/d' ~/.bashrc
+
 mysql -u jimv -p < update.sql
 mysql -u jimv -p < update.sql
 
 
 DEL S:IP:Used
 DEL S:IP:Used