foreman_fog_proxmox 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -14
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +6 -8
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +59 -60
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +2 -4
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume.js +10 -10
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cloudinit.js +0 -1
- data/app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb +80 -0
- data/app/controllers/concerns/foreman_fog_proxmox/hosts_controller.rb +53 -0
- data/app/helpers/proxmox_compute_resources_vms_helper.rb +99 -0
- data/app/helpers/proxmox_form_helper.rb +1 -1
- data/app/models/concerns/fog_extensions/proxmox/server.rb +3 -3
- data/app/models/concerns/host_ext/proxmox/associator.rb +46 -0
- data/app/models/concerns/host_ext/proxmox/for_vm.rb +33 -0
- data/app/models/concerns/orchestration/proxmox/compute.rb +18 -8
- data/app/models/foreman_fog_proxmox/proxmox.rb +4 -0
- data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +2 -6
- data/app/models/foreman_fog_proxmox/proxmox_images.rb +13 -4
- data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +14 -12
- data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +4 -2
- data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +2 -4
- data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +6 -1
- data/app/models/foreman_fog_proxmox/vms.rb +1 -1
- data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +1 -1
- data/app/services/concerns/foreman_fog_proxmox/compute_resource_host_associator.rb +34 -0
- data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_form.html.erb +2 -2
- data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_hosts_compute_detail_form.html.erb +4 -2
- data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +0 -1
- data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +2 -2
- data/app/views/compute_resources_vms/index/_proxmox.html.erb +2 -2
- data/lib/foreman_fog_proxmox/engine.rb +7 -1
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/test/unit/foreman_fog_proxmox/proxmox_images_test.rb +3 -3
- data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +40 -38
- metadata +9 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 19b7f2f30af319dbc8881900c660bf9ddc5026eb8762ace34dcd6b4ac7fa85f8
         | 
| 4 | 
            +
              data.tar.gz: 5430f62a1d7db829fddb142c468d5c3741a0090131f0a3d26746bec75f6b943e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ceac1a672eb780a7c7e8e05d8024f70d74d129a3ff48ad5d65f9947c78d60778a3697c7a70e030eff53346f3f56587a726fa71b5a719bb448bbea573d7970e47
         | 
| 7 | 
            +
              data.tar.gz: cd477463a37e43ce80db0986f08d8203b225cfc5abae4f31b5c165cfc149197c99be2b2d8687b6e217246609c77d781658d93c119b37c41bfebc6049be852b4a
         | 
    
        data/README.md
    CHANGED
    
    | @@ -34,12 +34,31 @@ You can support the plugin development via the following methods: | |
| 34 34 | 
             
            |>=0.12 |>=6.1|>=0.11|>=2.0|>=2.5|
         | 
| 35 35 | 
             
            |>=0.14 |>=6.2|=0.13.0|>=2.4|>=2.7|
         | 
| 36 36 | 
             
            |>=0.14 |>=6.2|>=0.13.1|>=2.3|>=2.5|
         | 
| 37 | 
            +
            |>=0.14 |>=6.2|>=0.14.0|>=2.5|>=2.5|
         | 
| 37 38 |  | 
| 38 39 | 
             
            ## Installation
         | 
| 39 40 |  | 
| 40 | 
            -
            ###  | 
| 41 | 
            +
            ### From OS packages
         | 
| 41 42 |  | 
| 42 | 
            -
             | 
| 43 | 
            +
            Please see the Foreman manual for complete instructions:
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            * [Foreman: How to Install a Plugin from package](https://theforeman.org/plugins/#2.Installation)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            [Install from package](https://theforeman.org/plugins/#2.2Packageinstallation) is the easiest way to install the plugin. Choose the latest release plugins repository. If you don't find it in the same foreman release repository, get it from the `nightly` repository.
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            Then you can install it with the package manager, in Debian/Ubuntu:
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            ```shell
         | 
| 52 | 
            +
            sudo apt-get install ruby-foreman-fog-proxmox
         | 
| 53 | 
            +
            ```
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            and in Fedora/Redhat Linux:
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ```shell
         | 
| 58 | 
            +
            sudo dnf install rubygem-foreman_fog_proxmox
         | 
| 59 | 
            +
            ```
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.theforeman.org/projects/foreman/wiki/SELinux) to allow foreman and all its plugins to work.
         | 
| 43 62 |  | 
| 44 63 | 
             
            ### From gem
         | 
| 45 64 |  | 
| @@ -47,10 +66,10 @@ See complete details in [plugin installation from gem](https://theforeman.org/pl | |
| 47 66 |  | 
| 48 67 | 
             
            Here is a Debian sample:
         | 
| 49 68 |  | 
| 50 | 
            -
            * Install foreman [from OS packages](https://theforeman.org/manuals/ | 
| 69 | 
            +
            * Install foreman [from OS packages](https://theforeman.org/manuals/latest/index.html#3.3InstallFromPackages):
         | 
| 51 70 |  | 
| 52 71 | 
             
            ```shell
         | 
| 53 | 
            -
            sudo apt install -y foreman foreman- | 
| 72 | 
            +
            sudo apt install -y foreman foreman-pgsql
         | 
| 54 73 | 
             
            ```
         | 
| 55 74 |  | 
| 56 75 | 
             
            * Use only foreman user (**not root!**) `sudo -u foreman ...`
         | 
| @@ -68,6 +87,8 @@ sudo -u foreman /usr/bin/foreman-ruby /usr/bin/bundle install | |
| 68 87 |  | 
| 69 88 | 
             
            * Precompile plugin assets:
         | 
| 70 89 |  | 
| 90 | 
            +
            You need [nodejs](https://nodejs.org/en/download/package-manager/) installed in order to use foreman-assets package.
         | 
| 91 | 
            +
             | 
| 71 92 | 
             
            ```shell
         | 
| 72 93 | 
             
            /usr/bin/foreman-ruby /usr/bin/bundle exec bin/rake plugin:assets:precompile[foreman_fog_proxmox]
         | 
| 73 94 | 
             
            ```
         | 
| @@ -98,14 +119,6 @@ Then you can check plugin installation after login into your new foreman server | |
| 98 119 | 
             
            
         | 
| 99 120 | 
             
            
         | 
| 100 121 |  | 
| 101 | 
            -
            ### From OS packages
         | 
| 102 | 
            -
             | 
| 103 | 
            -
            Please see the Foreman manual for complete instructions:
         | 
| 104 | 
            -
             | 
| 105 | 
            -
            * [Foreman: How to Install a Plugin](http://theforeman.org/manuals/latest/index.html#6.1InstallaPlugin)
         | 
| 106 | 
            -
             | 
| 107 | 
            -
            Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.theforeman.org/projects/foreman/wiki/SELinux) to allow foreman and all its plugins to work.
         | 
| 108 | 
            -
             | 
| 109 122 | 
             
            ## Usage
         | 
| 110 123 |  | 
| 111 124 | 
             
            * [Compute resource](.github/compute_resource.md)
         | 
| @@ -113,7 +126,7 @@ Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.thef | |
| 113 126 |  | 
| 114 127 | 
             
            ## Development
         | 
| 115 128 |  | 
| 116 | 
            -
            ###  | 
| 129 | 
            +
            ### Dev prerequisites
         | 
| 117 130 |  | 
| 118 131 | 
             
            * You need a Proxmox VE 5.4+ server running.
         | 
| 119 132 | 
             
            * You need ruby >= 2.5. You can install it with [asdf-vm](https://asdf-vm.com).
         | 
| @@ -189,7 +202,7 @@ add these lines to each environment in config/database.yml: | |
| 189 202 |  | 
| 190 203 | 
             
            ```shell
         | 
| 191 204 | 
             
            cp config/ignored_environments.yml.sample config/ignored_environments.yml
         | 
| 192 | 
            -
            docker run --name foreman-db -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
         | 
| 205 | 
            +
            docker run --name foreman-db -v foreman_data:/var/lib/postgresql/data -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
         | 
| 193 206 | 
             
            bundle exec bin/rake db:migrate
         | 
| 194 207 | 
             
            # reboot if settings.NAME error in schema
         | 
| 195 208 | 
             
            bundle exec bin/rake db:seed assets:precompile locale:pack webpack:compile
         | 
| @@ -15,8 +15,6 @@ | |
| 15 15 | 
             
            // You should have received a copy of the GNU General Public License
         | 
| 16 16 | 
             
            // along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
         | 
| 17 17 |  | 
| 18 | 
            -
            $(document).on('ContentLoad', tfm.numFields.initAll);
         | 
| 19 | 
            -
             | 
| 20 18 | 
             
            $(document).ready(function () {
         | 
| 21 19 | 
             
              sslVerifyPeerSelected();
         | 
| 22 20 | 
             
              authMethodSelected();
         | 
| @@ -36,14 +34,14 @@ function sslVerifyPeerSelected() { | |
| 36 34 | 
             
              }
         | 
| 37 35 | 
             
            }
         | 
| 38 36 |  | 
| 39 | 
            -
            function enableField( | 
| 40 | 
            -
              $( | 
| 41 | 
            -
              $( | 
| 37 | 
            +
            function enableField(item) {
         | 
| 38 | 
            +
              $(item).show();
         | 
| 39 | 
            +
              $(item).removeAttr('disabled');
         | 
| 42 40 | 
             
            }
         | 
| 43 41 |  | 
| 44 | 
            -
            function disableField( | 
| 45 | 
            -
              $( | 
| 46 | 
            -
              $( | 
| 42 | 
            +
            function disableField(item) {  
         | 
| 43 | 
            +
              $(item).hide();
         | 
| 44 | 
            +
              $(item).attr('disabled','disabled');
         | 
| 47 45 | 
             
            }
         | 
| 48 46 |  | 
| 49 47 | 
             
            function toggleFieldset(method, selected){
         | 
| @@ -15,7 +15,6 @@ | |
| 15 15 | 
             
            // You should have received a copy of the GNU General Public License
         | 
| 16 16 | 
             
            // along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
         | 
| 17 17 |  | 
| 18 | 
            -
            $(document).on('ContentLoad', tfm.numFields.initAll);
         | 
| 19 18 | 
             
            $(document).ready(vmTypeSelected);
         | 
| 20 19 |  | 
| 21 20 | 
             
            function vmTypeSelected() {
         | 
| @@ -39,17 +38,17 @@ function vmTypeSelected() { | |
| 39 38 | 
             
              return false;
         | 
| 40 39 | 
             
            }
         | 
| 41 40 |  | 
| 42 | 
            -
            function volumeButtonAddId( | 
| 43 | 
            -
              return $("a[data-association='" +  | 
| 41 | 
            +
            function volumeButtonAddId(item){
         | 
| 42 | 
            +
              return $("a[data-association='" + item + "_volumes']");
         | 
| 44 43 | 
             
            }
         | 
| 45 44 |  | 
| 46 | 
            -
            function volumeFieldsetId( | 
| 47 | 
            -
              return $("fieldset[id^='" + type + "_volume_"+  | 
| 45 | 
            +
            function volumeFieldsetId(item, type){
         | 
| 46 | 
            +
              return $("fieldset[id^='" + type + "_volume_"+ item +"']").not("fieldset[id$='_new_" + item +"_volumes']");
         | 
| 48 47 | 
             
            }
         | 
| 49 48 |  | 
| 50 | 
            -
            function indexByIdAndType( | 
| 51 | 
            -
               | 
| 52 | 
            -
              return  | 
| 49 | 
            +
            function indexByIdAndType(item, storage_type, vm_type){
         | 
| 50 | 
            +
              var regex = new RegExp(vm_type +"_volume_" + storage_type +"_(\\d+)");
         | 
| 51 | 
            +
              return item.match(regex)[1];
         | 
| 53 52 | 
             
            }
         | 
| 54 53 |  | 
| 55 54 | 
             
            function volidByIndexAndTag(index, tag){
         | 
| @@ -58,10 +57,10 @@ function volidByIndexAndTag(index, tag){ | |
| 58 57 |  | 
| 59 58 | 
             
            function hasCloudinit(){
         | 
| 60 59 | 
             
              result = false;
         | 
| 61 | 
            -
               | 
| 62 | 
            -
              if ( | 
| 63 | 
            -
                 | 
| 64 | 
            -
                 | 
| 60 | 
            +
              var volume_id = volumeFieldsetId('cloud_init', 'server').attr('id');
         | 
| 61 | 
            +
              if (volume_id !== undefined){
         | 
| 62 | 
            +
                var index = indexByIdAndType(volume_id, 'cloud_init', 'server');
         | 
| 63 | 
            +
                var volid = volidByIndexAndTag(index, 'input');
         | 
| 65 64 | 
             
                result = volid.includes("cloudinit");
         | 
| 66 65 | 
             
              }
         | 
| 67 66 | 
             
              return result;
         | 
| @@ -69,42 +68,42 @@ function hasCloudinit(){ | |
| 69 68 |  | 
| 70 69 | 
             
            function hasCdrom(){
         | 
| 71 70 | 
             
              result = false;
         | 
| 72 | 
            -
               | 
| 73 | 
            -
              if ( | 
| 74 | 
            -
                 | 
| 75 | 
            -
                 | 
| 76 | 
            -
                 | 
| 71 | 
            +
              var volume_id = volumeFieldsetId('cdrom', 'server').attr('id');
         | 
| 72 | 
            +
              if (volume_id !== undefined){
         | 
| 73 | 
            +
                var index = indexByIdAndType(volume_id, 'cdrom', 'server');
         | 
| 74 | 
            +
                var checked = $("input[id^='host_compute_attributes_volumes_attributes_" + index + "_cdrom']:checked").val();
         | 
| 75 | 
            +
                var isCdrom = checked === 'cdrom';
         | 
| 77 76 | 
             
                result = isCdrom;
         | 
| 78 | 
            -
                 | 
| 77 | 
            +
                var isImage = checked === 'image';
         | 
| 79 78 | 
             
                if (isImage) {
         | 
| 80 | 
            -
                   | 
| 79 | 
            +
                  var volid = volidByIndexAndTag(index, 'select');
         | 
| 81 80 | 
             
                  result = volid.includes("iso");
         | 
| 82 81 | 
             
                }
         | 
| 83 82 | 
             
              }
         | 
| 84 83 | 
             
              return result;
         | 
| 85 84 | 
             
            }
         | 
| 86 85 |  | 
| 87 | 
            -
            function cloudinit( | 
| 88 | 
            -
              return  | 
| 86 | 
            +
            function cloudinit(item){
         | 
| 87 | 
            +
              return item === 'cloud_init' && hasCloudinit();
         | 
| 89 88 | 
             
            }
         | 
| 90 89 |  | 
| 91 | 
            -
            function cdrom( | 
| 92 | 
            -
              return  | 
| 90 | 
            +
            function cdrom(item){
         | 
| 91 | 
            +
              return item === 'cdrom' && hasCdrom();
         | 
| 93 92 | 
             
            }
         | 
| 94 93 |  | 
| 95 | 
            -
            function enableVolume( | 
| 96 | 
            -
              volumeFieldsetId( | 
| 97 | 
            -
              volumeButtonAddId( | 
| 98 | 
            -
              if (cloudinit( | 
| 99 | 
            -
                volumeButtonAddId( | 
| 94 | 
            +
            function enableVolume(volume_id, type){
         | 
| 95 | 
            +
              volumeFieldsetId(volume_id, type).show();
         | 
| 96 | 
            +
              volumeButtonAddId(volume_id).show();
         | 
| 97 | 
            +
              if (cloudinit(volume_id) || cdrom(volume_id)){
         | 
| 98 | 
            +
                volumeButtonAddId(volume_id).hide();
         | 
| 100 99 | 
             
              }
         | 
| 101 | 
            -
              volumeFieldsetId( | 
| 100 | 
            +
              volumeFieldsetId(volume_id, type).removeAttr('disabled');
         | 
| 102 101 | 
             
            }
         | 
| 103 102 |  | 
| 104 | 
            -
            function disableVolume( | 
| 105 | 
            -
              volumeFieldsetId( | 
| 106 | 
            -
              volumeButtonAddId( | 
| 107 | 
            -
              volumeFieldsetId( | 
| 103 | 
            +
            function disableVolume(volume_id, type){
         | 
| 104 | 
            +
              volumeFieldsetId(volume_id, type).hide();
         | 
| 105 | 
            +
              volumeButtonAddId(volume_id).hide();
         | 
| 106 | 
            +
              volumeFieldsetId(volume_id, type).attr('disabled','disabled');
         | 
| 108 107 | 
             
            }
         | 
| 109 108 |  | 
| 110 109 | 
             
            function volumes(type){
         | 
| @@ -115,44 +114,44 @@ function volume(type){ | |
| 115 114 | 
             
              return type === 'qemu' ? 'server' : 'container';
         | 
| 116 115 | 
             
            }
         | 
| 117 116 |  | 
| 118 | 
            -
            function toggleVolume( | 
| 119 | 
            -
              type1 === type2 ? enableVolume( | 
| 117 | 
            +
            function toggleVolume(volume_id, type1, type2){
         | 
| 118 | 
            +
              type1 === type2 ? enableVolume(volume_id, volume(type1)) : disableVolume(volume_id, volume(type1));
         | 
| 120 119 | 
             
            }
         | 
| 121 120 |  | 
| 122 121 | 
             
            function toggleVolumes(selected){
         | 
| 123 122 | 
             
               ['qemu', 'lxc'].forEach(function(type){
         | 
| 124 | 
            -
                volumes(type).forEach(function( | 
| 125 | 
            -
                  toggleVolume( | 
| 123 | 
            +
                volumes(type).forEach(function(volume_id){
         | 
| 124 | 
            +
                  toggleVolume(volume_id, selected, type);
         | 
| 126 125 | 
             
                });
         | 
| 127 126 | 
             
              });
         | 
| 128 127 | 
             
            }
         | 
| 129 128 |  | 
| 130 | 
            -
            function enableFieldset( | 
| 129 | 
            +
            function enableFieldset(fieldsetId, fieldset) {
         | 
| 131 130 | 
             
              if (fieldset.toggle && fieldset.new_vm){
         | 
| 132 | 
            -
                fieldset_id( | 
| 131 | 
            +
                fieldset_id(fieldsetId, fieldset).show();
         | 
| 133 132 | 
             
              }
         | 
| 134 | 
            -
              fieldset_id( | 
| 135 | 
            -
              input_hidden_id( | 
| 133 | 
            +
              fieldset_id(fieldsetId, fieldset).removeAttr('disabled');
         | 
| 134 | 
            +
              input_hidden_id(fieldsetId).removeAttr('disabled');
         | 
| 136 135 | 
             
            }
         | 
| 137 136 |  | 
| 138 | 
            -
            function disableFieldset( | 
| 137 | 
            +
            function disableFieldset(fieldsetId, fieldset) {  
         | 
| 139 138 | 
             
              if (fieldset.toggle && fieldset.new_vm){
         | 
| 140 | 
            -
                fieldset_id( | 
| 139 | 
            +
                fieldset_id(fieldsetId, fieldset).hide();
         | 
| 141 140 | 
             
              }
         | 
| 142 | 
            -
              fieldset_id( | 
| 143 | 
            -
              input_hidden_id( | 
| 141 | 
            +
              fieldset_id(fieldsetId, fieldset).attr('disabled','disabled');
         | 
| 142 | 
            +
              input_hidden_id(fieldsetId).attr('disabled','disabled');
         | 
| 144 143 | 
             
            }
         | 
| 145 144 |  | 
| 146 | 
            -
            function toggleFieldset( | 
| 147 | 
            -
              type1 === type2 ? enableFieldset( | 
| 145 | 
            +
            function toggleFieldset(fieldsetId, fieldset, type1, type2) {  
         | 
| 146 | 
            +
              type1 === type2 ? enableFieldset(fieldsetId, fieldset) : disableFieldset(fieldsetId, fieldset);
         | 
| 148 147 | 
             
            }
         | 
| 149 148 |  | 
| 150 | 
            -
            function input_hidden_id( | 
| 151 | 
            -
              return $("div[id^='"+  | 
| 149 | 
            +
            function input_hidden_id(volume_id){
         | 
| 150 | 
            +
              return $("div[id^='"+ volume_id +"_volumes']" + " + input:hidden");
         | 
| 152 151 | 
             
            }
         | 
| 153 152 |  | 
| 154 | 
            -
            function fieldset_id( | 
| 155 | 
            -
              return $("fieldset[id^='" +  | 
| 153 | 
            +
            function fieldset_id(fieldsetId, fieldset){
         | 
| 154 | 
            +
              return $("fieldset[id^='" + fieldsetId + "_"+fieldset.id+"']");
         | 
| 156 155 | 
             
            }
         | 
| 157 156 |  | 
| 158 157 | 
             
            function fieldsets(type){
         | 
| @@ -163,8 +162,8 @@ function toggleFieldsets(fieldset){ | |
| 163 162 | 
             
              var removable_input_hidden = $("div.removable-item[style='display: none;']" + " + input:hidden");
         | 
| 164 163 | 
             
              removable_input_hidden.attr('disabled','disabled');  
         | 
| 165 164 | 
             
              ['qemu', 'lxc'].forEach(function(type){
         | 
| 166 | 
            -
                fieldsets(type).forEach(function( | 
| 167 | 
            -
                  toggleFieldset( | 
| 165 | 
            +
                fieldsets(type).forEach(function(fieldsetId){
         | 
| 166 | 
            +
                  toggleFieldset(fieldsetId, fieldset, fieldset.selected, type);
         | 
| 168 167 | 
             
                });
         | 
| 169 168 | 
             
              });
         | 
| 170 169 | 
             
            }
         | 
| @@ -190,18 +189,18 @@ function nodeSelected(item) { | |
| 190 189 | 
             
              }
         | 
| 191 190 | 
             
            }
         | 
| 192 191 |  | 
| 193 | 
            -
            function emptySelect( | 
| 194 | 
            -
              $( | 
| 195 | 
            -
              $( | 
| 196 | 
            -
              $( | 
| 192 | 
            +
            function emptySelect(select_id){
         | 
| 193 | 
            +
              $(select_id).empty();
         | 
| 194 | 
            +
              $(select_id).append($("<option></option>").val('').text(''));
         | 
| 195 | 
            +
              $(select_id).val('');
         | 
| 197 196 | 
             
            }
         | 
| 198 197 |  | 
| 199 198 | 
             
            function initOptions(select_ids){
         | 
| 200 199 | 
             
              console.log('initOptions(' + select_ids[0] + ')');
         | 
| 201 200 | 
             
              select_ids.forEach(emptySelect);
         | 
| 202 | 
            -
              select_ids.forEach(function( | 
| 203 | 
            -
                $( | 
| 204 | 
            -
                $( | 
| 201 | 
            +
              select_ids.forEach(function(select_id){
         | 
| 202 | 
            +
                $(select_id + ' option:selected').prop('selected',false);
         | 
| 203 | 
            +
                $(select_id).val('');
         | 
| 205 204 | 
             
              });
         | 
| 206 205 | 
             
            }
         | 
| 207 206 |  | 
| @@ -24,9 +24,9 @@ function volumesAttributesSelector(profile,index,selector) { | |
| 24 24 | 
             
            }
         | 
| 25 25 |  | 
| 26 26 | 
             
            function getIndex(item) {
         | 
| 27 | 
            -
              var  | 
| 27 | 
            +
              var index_id = $(item).attr('id');
         | 
| 28 28 | 
             
              var pattern = /(host_compute_attributes_volumes_attributes_||compute_attribute_vm_attrs_volumes_attributes_)(\d+)[_](.*)/i;
         | 
| 29 | 
            -
              pattern_a = pattern.exec( | 
| 29 | 
            +
              pattern_a = pattern.exec(index_id);
         | 
| 30 30 | 
             
              var index = pattern_a[2];
         | 
| 31 31 | 
             
              return index;
         | 
| 32 32 | 
             
            }
         | 
| @@ -46,7 +46,6 @@ function controllerSelected(item) { | |
| 46 46 | 
             
              var device = $(device_selector).limitedSpinner('value');
         | 
| 47 47 | 
             
              var id = controller + device;
         | 
| 48 48 | 
             
              $(id_selector).val(id);
         | 
| 49 | 
            -
              tfm.numFields.initAll();
         | 
| 50 49 | 
             
            }
         | 
| 51 50 |  | 
| 52 51 | 
             
            function deviceSelected(item) {
         | 
| @@ -58,7 +57,6 @@ function deviceSelected(item) { | |
| 58 57 | 
             
              var controller = $(controller_selector).val();
         | 
| 59 58 | 
             
              var id = controller + device;
         | 
| 60 59 | 
             
              $(id_selector).val(id);
         | 
| 61 | 
            -
              tfm.numFields.initAll();
         | 
| 62 60 | 
             
            }
         | 
| 63 61 |  | 
| 64 62 | 
             
            function computeControllerMaxDevice(controller) {
         | 
| @@ -16,24 +16,24 @@ | |
| 16 16 | 
             
            // along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
         | 
| 17 17 |  | 
| 18 18 | 
             
            function getIndex(item) {
         | 
| 19 | 
            -
              var  | 
| 19 | 
            +
              var index_id = $(item).attr('id');
         | 
| 20 20 | 
             
              var pattern = /(host_compute_attributes_volumes_attributes_||compute_attribute_vm_attrs_volumes_attributes_)(\d+)[_](.*)/i;
         | 
| 21 | 
            -
              pattern_a = pattern.exec( | 
| 21 | 
            +
              pattern_a = pattern.exec(index_id);
         | 
| 22 22 | 
             
              var index = pattern_a[2];
         | 
| 23 23 | 
             
              return index;
         | 
| 24 24 | 
             
            }
         | 
| 25 25 |  | 
| 26 26 | 
             
            function volumeId(type,index){
         | 
| 27 | 
            -
               | 
| 28 | 
            -
              return  | 
| 27 | 
            +
              var volume_id = '#volume_' + type + '_' + index;
         | 
| 28 | 
            +
              return volume_id;
         | 
| 29 29 | 
             
            }
         | 
| 30 30 |  | 
| 31 | 
            -
            function enableField( | 
| 32 | 
            -
              $( | 
| 33 | 
            -
              $( | 
| 31 | 
            +
            function enableField(item) {
         | 
| 32 | 
            +
              $(item).show();
         | 
| 33 | 
            +
              $(item).removeAttr('disabled');
         | 
| 34 34 | 
             
            }
         | 
| 35 35 |  | 
| 36 | 
            -
            function disableField( | 
| 37 | 
            -
              $( | 
| 38 | 
            -
              $( | 
| 36 | 
            +
            function disableField(item) {  
         | 
| 37 | 
            +
              $(item).hide();
         | 
| 38 | 
            +
              $(item).attr('disabled','disabled');
         | 
| 39 39 | 
             
            }
         | 
| @@ -21,5 +21,4 @@ function cloudinitControllerSelected(item) { | |
| 21 21 | 
             
              var max = computeControllerMaxDevice(controller);
         | 
| 22 22 | 
             
              var device_selector = 'host_compute_attributes_volumes_attributes_' + index + 'device';
         | 
| 23 23 | 
             
              $(device_selector).attr('data-soft-max', max);
         | 
| 24 | 
            -
              tfm.numFields.initAll();
         | 
| 25 24 | 
             
            }
         | 
| @@ -0,0 +1,80 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Copyright 2021 Tristan Robert
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # This file is part of ForemanFogProxmox.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # ForemanFogProxmox is free software: you can redistribute it and/or modify
         | 
| 8 | 
            +
            # it under the terms of the GNU General Public License as published by
         | 
| 9 | 
            +
            # the Free Software Foundation, either version 3 of the License, or
         | 
| 10 | 
            +
            # (at your option) any later version.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # ForemanFogProxmox is distributed in the hope that it will be useful,
         | 
| 13 | 
            +
            # but WITHOUT ANY WARRANTY; without even the implied warranty of
         | 
| 14 | 
            +
            # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
         | 
| 15 | 
            +
            # GNU General Public License for more details.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            # You should have received a copy of the GNU General Public License
         | 
| 18 | 
            +
            # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            module ForemanFogProxmox
         | 
| 21 | 
            +
              module ComputeResourcesVmsController
         | 
| 22 | 
            +
                extend ActiveSupport::Concern
         | 
| 23 | 
            +
                included do
         | 
| 24 | 
            +
                  prepend Overrides
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                module Overrides
         | 
| 27 | 
            +
                  def associate
         | 
| 28 | 
            +
                    if Host.for_vm_uuid(@compute_resource, @vm).any?
         | 
| 29 | 
            +
                      process_error(:error_msg => _("VM already associated with a host"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
         | 
| 30 | 
            +
                      return
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                    host = @compute_resource.associated_host(@vm) if @compute_resource.respond_to?(:associated_host)
         | 
| 33 | 
            +
                    if host.present?
         | 
| 34 | 
            +
                      host.associate!(@compute_resource, @vm)
         | 
| 35 | 
            +
                      process_success(:success_msg => _("VM associated to host %s") % host.name, :success_redirect => host_path(host))
         | 
| 36 | 
            +
                    else
         | 
| 37 | 
            +
                      process_error(:error_msg => _("No host found to associate this VM with"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def console
         | 
| 42 | 
            +
                    @console = @compute_resource.console proxmox_vm_id(@compute_resource, @vm)
         | 
| 43 | 
            +
                    render case @console[:type]
         | 
| 44 | 
            +
                           when 'spice'
         | 
| 45 | 
            +
                             'hosts/console/spice'
         | 
| 46 | 
            +
                           when 'vnc'
         | 
| 47 | 
            +
                             'hosts/console/vnc'
         | 
| 48 | 
            +
                           when 'vmrc'
         | 
| 49 | 
            +
                             'hosts/console/vmrc'
         | 
| 50 | 
            +
                           else
         | 
| 51 | 
            +
                             'hosts/console/log'
         | 
| 52 | 
            +
                           end
         | 
| 53 | 
            +
                  rescue StandardError => e
         | 
| 54 | 
            +
                    process_error :redirect => compute_resource_vm_path(@compute_resource, proxmox_vm_id(@compute_resource, @vm)), :error_msg => (_("Failed to set console: %s") % e), :object => @vm
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  private
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def proxmox_vm_id(compute_resource, vm)
         | 
| 60 | 
            +
                    id = vm.identity
         | 
| 61 | 
            +
                    id = vm.unique_cluster_identity(compute_resource) if compute_resource.class == ForemanFogProxmox::Proxmox
         | 
| 62 | 
            +
                    id
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def run_vm_action(action)
         | 
| 66 | 
            +
                    if @vm.send(action)
         | 
| 67 | 
            +
                      @vm.reload
         | 
| 68 | 
            +
                      success format(_("%<vm>s is now %<vm_state>s"), { :vm => @vm, :vm_state => @vm.state.capitalize })
         | 
| 69 | 
            +
                    else
         | 
| 70 | 
            +
                      error format(_("failed to %<action>s %<vm>s"), { :action => _(action), :vm => @vm })
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
                    redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
         | 
| 73 | 
            +
                  # This should only rescue Fog::Errors, but Fog returns all kinds of errors...
         | 
| 74 | 
            +
                  rescue StandardError => e
         | 
| 75 | 
            +
                    error format(_("Error - %<message>s"), { :message => _(e.message) })
         | 
| 76 | 
            +
                    redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
            end
         |