Quellcode durchsuchen

实现虚拟机开机启动

James Iter vor 7 Jahren
Ursprung
Commit
effd8d86b2

+ 52 - 0
jimvc/api/guest.py

@@ -92,6 +92,11 @@ def r_create():
             Rules.SERVICE_ID.value
         )
 
+    if 'autostart' in request.json:
+        args_rules.append(
+            Rules.AUTOSTART.value
+        )
+
     try:
         ret = dict()
         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.label = ji.Common.generate_random_code(length=8)
             guest.remark = request.json.get('remark', '')
+            guest.autostart = request.json.get('autostart', False)
 
             guest.password = request.json.get('password')
             if guest.password is None or guest.password.__len__() < 1:
@@ -300,6 +306,7 @@ def r_create():
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
                 'node_id': guest.node_id,
+                'autostart': guest.autostart,
                 'name': guest.label,
                 'template_path': os_template_image.path,
                 'os_type': os_template_profile.os_type,
@@ -317,6 +324,51 @@ def r_create():
         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
 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操作
 # 创建虚拟机
 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, '/_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'])

+ 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.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':
                 cls.disk.uuid = cls.message['message']['passback_parameters']['disk_uuid']
                 cls.disk.get_by('uuid')

+ 5 - 2
jimvc/models/guest.py

@@ -25,6 +25,7 @@ class Guest(ORM):
         self.id = 0
         self.uuid = None
         self.label = None
+        self.autostart = False
         self.password = None
         self.remark = ''
         self.os_template_image_id = None
@@ -49,6 +50,7 @@ class Guest(ORM):
             'id': FilterFieldType.INT.value,
             'uuid': FilterFieldType.STR.value,
             'label': FilterFieldType.STR.value,
+            'autostart': FilterFieldType.BOOL.value,
             'status': FilterFieldType.INT.value,
             'remark': FilterFieldType.STR.value,
             'node_id': FilterFieldType.INT.value,
@@ -59,11 +61,12 @@ class Guest(ORM):
 
     @staticmethod
     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
     def get_allow_content_search_keywords():
-        return ['label', 'remark', 'node_id', 'ip']
+        return ['label', 'autostart', 'remark', 'node_id', 'ip']
 
 
 class Disk(ORM):

+ 1 - 0
jimvc/models/rules.py

@@ -71,6 +71,7 @@ class Rules(Enum):
     UUID = (basestring, 'uuid', (36, 36))
     NODE_ID = (basestring, 'node_id', (16, 16))
     UUIDS = (REG_UUIDS, 'uuids')
+    AUTOSTART = (int, 'autostart')
     CPU = (int, 'cpu')
     MEMORY = (int, 'memory')
     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();
     }
 
+    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) {
         $.ajax({
             url : '/api/guests/_boot/' + uuids.join(','),
@@ -918,6 +935,16 @@
         $('#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) {
         var uuid = $('#instance_uuid').val();
         allocate_bandwidth([uuid], $('#bandwidth').val(), $('#bandwidth_unit').val());
@@ -1087,6 +1114,22 @@
         $('#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() {
         var uuids = get_checked_uuids();
         if (uuids) {
@@ -1286,6 +1329,7 @@
                 '<td width="40px" style="padding-left: 12px;">' +
                     '<span class="' + guest.html.logo + '" title="' + guest.html.os_template_label + '"></span>' +
                 '</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.hostname + '</td>' +
                 '<td>' +
@@ -1680,8 +1724,7 @@
                         {% endif %}
                     </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>{{ format_guest_status(item.status, item.progress)|safe }}</td>
                     <td>{{ hosts_mapping_by_node_id[item.node_id | string].hostname }}</td>
@@ -1883,6 +1926,12 @@
                                                 </ul>
                                             </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>
                                                 <a href="javascript:;" data-toggle="modal" data-target="#batch_allocate_bandwidth_modal">分配带宽</a>
                                             </li>
@@ -2748,4 +2797,42 @@
         </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 %}

+ 2 - 0
misc/init.sql

@@ -32,6 +32,7 @@ CREATE TABLE IF NOT EXISTS guest(
     label VARCHAR(64) NOT NULL UNIQUE,
     password VARCHAR(255) NOT NULL,
     remark VARCHAR(255) NOT NULL DEFAULT '',
+    autostart BOOLEAN NOT NULL DEFAULT FALSE,
     os_template_image_id BIGINT UNSIGNED NOT NULL,
     create_time BIGINT UNSIGNED NOT NULL,
     -- 运行时的状态用 status;
@@ -56,6 +57,7 @@ CREATE TABLE IF NOT EXISTS guest(
 
 ALTER TABLE guest ADD INDEX (uuid);
 ALTER TABLE guest ADD INDEX (label);
+ALTER TABLE guest ADD INDEX (autostart);
 ALTER TABLE guest ADD INDEX (node_id);
 ALTER TABLE guest ADD INDEX (service_id);
 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;
 
 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
 
 deactivate
+sed -i '/\/usr\/local\/venv-jimv\/bin\/activate/d' ~/.bashrc
+
 mysql -u jimv -p < update.sql
 
 DEL S:IP:Used