Tomas Jelinek has uploaded a new change for review.

Change subject: webadmin: instnace types added to VM dialog
......................................................................

webadmin: instnace types added to VM dialog

WIP - do not review

Change-Id: Id16e521a4ccde46ec967075a3c643fda254e6fde
Signed-off-by: Tomas Jelinek <[email protected]>
---
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
A 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/AttachedToInstanceTypeManager.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
M 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/pools/BaseVmListModelTest.java
9 files changed, 172 insertions(+), 35 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/83/24583/1

diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
index 1bba729..f78aa8d 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
@@ -1693,4 +1693,7 @@
 
     @DefaultStringValue("Description")
     String descriptionInstanceTypeGeneral();
+
+    @DefaultStringValue("Custom")
+    String customInstanceType();
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
index 4528f2a..7985e5c 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
@@ -220,7 +220,6 @@
     protected DialogTab systemTab;
 
     @UiField(provided = true)
-//    @WithElementId("memSize")
     public EntityModelDetachableWidget detachableMemSizeEditor;
 
     @Path(value = "memSize.entity")
@@ -978,20 +977,32 @@
         vmTypeEditor = new ListModelListBoxEditor<VmType>(new EnumRenderer(), 
new ModeSwitchingVisibilityRenderer());
 
         instanceTypesEditor = new 
ListModelTypeAheadListBoxEditor<InstanceType>(
-                new 
ListModelTypeAheadListBoxEditor.NullSafeSuggestBoxRenderer<InstanceType>() {
+                new 
ListModelTypeAheadListBoxEditor.SuggestBoxRenderer<InstanceType>() {
 
                     @Override
-                    public String getReplacementStringNullSafe(InstanceType 
data) {
-                        return data.getName();
+                    public String getReplacementString(InstanceType data) {
+                        if (data != null) {
+                            return data.getName();
+                        }
+
+                        return constants.customInstanceType();
                     }
 
                     @Override
-                    public String getDisplayStringNullSafe(InstanceType data) {
+                    public String getDisplayString(InstanceType data) {
+                        if (data != null) {
+                            return typeAheadNameDescriptionTemplateNullSafe(
+                                    data.getName(),
+                                    data.getDescription()
+                            );
+                        }
+
                         return typeAheadNameDescriptionTemplateNullSafe(
-                                data.getName(),
-                                data.getDescription()
+                                constants.customInstanceType(),
+                                constants.customInstanceType()
                         );
                     }
+
                 },
                 new ModeSwitchingVisibilityRenderer()
         );
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
index 3776598..760b264 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
@@ -13,5 +13,6 @@
     protected void build(UnitVmModel model, VM vm) {
         vm.setVmtGuid(model.getTemplate().getSelectedItem().getId());
         vm.setCustomProperties(model.getCustomPropertySheet().serialize());
+        vm.setInstanceTypeId(model.getInstanceTypes().getSelectedItem() != 
null ? model.getInstanceTypes().getSelectedItem().getId() : null);
     }
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/AttachedToInstanceTypeManager.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/AttachedToInstanceTypeManager.java
new file mode 100644
index 0000000..55d4f0e
--- /dev/null
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/AttachedToInstanceTypeManager.java
@@ -0,0 +1,56 @@
+package org.ovirt.engine.ui.uicommonweb.models.vms;
+
+import org.ovirt.engine.ui.uicompat.Event;
+import org.ovirt.engine.ui.uicompat.EventArgs;
+import org.ovirt.engine.ui.uicompat.IEventListener;
+
+public class AttachedToInstanceTypeManager implements IEventListener {
+
+    private UnitVmModel model;
+
+    // needs explicit activation after the whole model is fully populated
+    private boolean active = false;
+
+    public AttachedToInstanceTypeManager(UnitVmModel model) {
+        this.model = model;
+        
this.model.getInstanceTypes().getSelectedItemChangedEvent().addListener(this);
+
+        registerFieldsAttachedToInstanceType();
+    }
+
+    public void activate() {
+        active = true;
+    }
+
+    public void deactivate() {
+        active = false;
+    }
+
+    private void registerFieldsAttachedToInstanceType() {
+        model.getMemSize().getEntityChangedEvent().addListener(this);
+    }
+
+    @Override
+    public void eventRaised(Event ev, Object sender, EventArgs args) {
+        if (!active) {
+            return;
+        }
+
+        boolean attached = model.getAttachedToInstanceType().getEntity();
+        boolean instanceTypeChanged = sender == model.getInstanceTypes();
+        boolean customInstanceType = 
model.getInstanceTypes().getSelectedItem() == null;
+
+        if (instanceTypeChanged && !attached) {
+            // if the instance type changed attach again to the new instance 
type
+            model.getAttachedToInstanceType().setEntity(true);
+        }
+
+        if (attached && !customInstanceType && !instanceTypeChanged) {
+            // detach if attached to some real (not custom) instance type
+            model.getAttachedToInstanceType().setEntity(false);
+            deactivate();
+            model.getInstanceTypes().setSelectedItem(null);
+            activate();
+        }
+    }
+}
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
index 162d7cf..f5f15a2 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
@@ -34,6 +34,8 @@
 {
     private EditProfileBehavior networkBehavior = new EditProfileBehavior();
 
+    private AttachedToInstanceTypeManager attachedToInstanceTypeManager;
+
     protected VM vm;
 
     private List<VmNetworkInterface> networkInerfaces;
@@ -56,6 +58,9 @@
     @Override
     public void initialize(SystemTreeItemModel systemTreeSelectedItem) {
         super.initialize(systemTreeSelectedItem);
+
+        attachedToInstanceTypeManager = new 
AttachedToInstanceTypeManager(getModel());
+
         getModel().getVmInitEnabled().setEntity(getVm().getVmInit() != null);
         getModel().getVmInitModel().init(getVm().getStaticData());
         getModel().getVmType().setIsChangable(true);
@@ -86,6 +91,8 @@
                 }
             }
         }), vm.getId());
+
+        attachedToInstanceTypeManager.activate();
     }
 
     private void postNetworkInterfacesLoaded() {
@@ -289,6 +296,8 @@
                 }
             }), vm.getRunOnVds());
         }
+
+        initInstanceTypes(vm.getInstanceTypeId());
     }
 
     private int calculateHostCpus() {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
index aa9c5b3..ab9f122 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
@@ -10,9 +10,7 @@
 import org.ovirt.engine.core.common.businessentities.VmType;
 import 
org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
 import org.ovirt.engine.core.common.businessentities.network.VnicProfileView;
-import org.ovirt.engine.core.common.interfaces.SearchType;
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
-import org.ovirt.engine.core.common.queries.SearchParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
 import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.compat.Guid;
@@ -34,10 +32,15 @@
 
     private final ProfileBehavior networkBehavior = new EditProfileBehavior();
 
+    private AttachedToInstanceTypeManager attachedToInstanceTypeManager;
+
     @Override
     public void initialize(SystemTreeItemModel systemTreeSelectedItem)
     {
         super.initialize(systemTreeSelectedItem);
+
+        attachedToInstanceTypeManager = new 
AttachedToInstanceTypeManager(getModel());
+
         getModel().getIsSoundcardEnabled().setIsChangable(true);
         getModel().getVmType().setIsChangable(true);
 
@@ -79,24 +82,9 @@
 
         initPriority(0);
         getModel().getVmInitModel().init(null);
-        initInstanceTypes();
-    }
 
-    private void initInstanceTypes() {
-        SearchParameters params = new SearchParameters("Instancetypes:", 
SearchType.InstanceType, true); //$NON-NLS-1$
-        AsyncQuery query = new AsyncQuery();
-        query.setModel(this);
-        query.asyncCallback = new INewAsyncCallback() {
-            @Override
-            public void onSuccess(Object model, Object returnValue) {
-                if (returnValue != null) {
-                    VdcQueryReturnValue res = (VdcQueryReturnValue) 
returnValue;
-                    
getModel().getInstanceTypes().setItems((Iterable<InstanceType>) 
res.getReturnValue());
-                }
-            }
-        };
-
-        Frontend.getInstance().runQuery(VdcQueryType.Search, params, query);
+        // by default select the empty instance type
+        initInstanceTypes(null);
     }
 
     @Override
@@ -122,7 +110,6 @@
             
getModel().getNumOfSockets().setSelectedItem(template.getNumOfSockets());
             
getModel().getNumOfMonitors().setSelectedItem(template.getNumOfMonitors());
             
getModel().getIsSingleQxlEnabled().setEntity(template.getSingleQxlPci());
-            getModel().getMemSize().setEntity(template.getMemSizeMb());
             getModel().setBootSequence(template.getDefaultBootSequence());
             
getModel().getIsHighlyAvailable().setEntity(template.isAutoStartup());
 
@@ -214,9 +201,33 @@
             updateNetworkInterfacesByTemplate(template);
             getModel().getVmInitModel().init(template);
             getModel().getVmInitEnabled().setEntity(template.getVmInit() != 
null);
+
+            if (getModel().getInstanceTypes().getSelectedItem() == null) {
+                // only if the instance type is not selected use the template
+                updateInstanceTypeFieldsFrom(template);
+            }
+
+            attachedToInstanceTypeManager.activate();
         }
     }
 
+    @Override
+    public void instanceTypeSelectedItemChanged() {
+        super.instanceTypeSelectedItemChanged();
+
+        InstanceType instanceType = 
getModel().getInstanceTypes().getSelectedItem();
+        if (instanceType != null) {
+            // the instance type is in fact a template
+            updateInstanceTypeFieldsFrom((VmTemplate) instanceType);
+        }
+    }
+
+    private void updateInstanceTypeFieldsFrom(VmTemplate template) {
+        attachedToInstanceTypeManager.deactivate();
+        getModel().getMemSize().setEntity(template.getMemSizeMb());
+        attachedToInstanceTypeManager.activate();
+    }
+
     private void setSelectedOSById (int osId) {
         for (Integer osIdList : getModel().getOSType().getItems()) {
             if (osIdList.intValue() == osId) {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
index be5ba41..6f89a5b 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
@@ -1491,6 +1491,7 @@
 
         setEditingEnabled(new EntityModel<Boolean>());
         getEditingEnabled().setEntity(true);
+
     }
 
     public void initialize(SystemTreeItemModel SystemTreeSelectedItem)
@@ -1556,7 +1557,7 @@
             {
                 template_SelectedItemChanged(sender, args);
             } else if (sender == getInstanceTypes()) {
-                instanceTypeSelectedItemChanged();
+                behavior.instanceTypeSelectedItemChanged();
             } else if (sender == getTimeZone())
             {
                 timeZone_SelectedItemChanged(sender, args);
@@ -1572,9 +1573,6 @@
                 getVmInitModel().osTypeChanged(getOSType().getSelectedItem());
                 updateDisplayProtocol();
                 initUsbPolicy();
-
-                // TODO Test
-                
getAttachedToInstanceType().setEntity(!getAttachedToInstanceType().getEntity());
             }
             else if (sender == getFirstBootDevice())
             {
@@ -1661,10 +1659,6 @@
             // for the "other" also use cloud init
             getCloudInitEnabled().setEntity(!getIsWindowsOS());
         }
-    }
-
-    private void instanceTypeSelectedItemChanged() {
-        // TODO
     }
 
     private void vmTypeChanged() {
@@ -2752,4 +2746,5 @@
         getOverrideMigrationDowntime().setEntity(value != null);
         getMigrationDowntime().setEntity(value);
     }
+
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
index b6c2dd7..cf751fe 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
@@ -15,6 +15,7 @@
 import org.ovirt.engine.core.common.businessentities.DiskImage;
 import org.ovirt.engine.core.common.businessentities.DiskInterface;
 import org.ovirt.engine.core.common.businessentities.DisplayType;
+import org.ovirt.engine.core.common.businessentities.InstanceType;
 import org.ovirt.engine.core.common.businessentities.MigrationSupport;
 import org.ovirt.engine.core.common.businessentities.Quota;
 import org.ovirt.engine.core.common.businessentities.QuotaEnforcementTypeEnum;
@@ -29,8 +30,10 @@
 import 
org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
 import 
org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
 import org.ovirt.engine.core.common.businessentities.network.VnicProfileView;
+import org.ovirt.engine.core.common.interfaces.SearchType;
 import org.ovirt.engine.core.common.queries.ConfigurationValues;
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.SearchParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
 import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.compat.Guid;
@@ -98,6 +101,10 @@
         }
 
         postDataCenterWithClusterSelectedItemChanged();
+    }
+
+    public void instanceTypeSelectedItemChanged() {
+
     }
 
     protected void updateMigrationForLocalSD() {
@@ -1240,4 +1247,42 @@
 
         return cluster.getcompatibility_version();
     }
+
+    protected void initInstanceTypes(final Guid selectedInstanceTypeId) {
+        SearchParameters params = new SearchParameters("Instancetypes:", 
SearchType.InstanceType, true); //$NON-NLS-1$
+        AsyncQuery query = new AsyncQuery();
+        query.setModel(this);
+        query.asyncCallback = new INewAsyncCallback() {
+            @Override
+            public void onSuccess(Object model, Object returnValue) {
+                if (returnValue != null) {
+                    VdcQueryReturnValue res = (VdcQueryReturnValue) 
returnValue;
+
+                    List<InstanceType> instanceTypes = new 
ArrayList<InstanceType>();
+                    instanceTypes.add(null);
+
+                    for (InstanceType instanceType : (Iterable<InstanceType>) 
res.getReturnValue()) {
+                        instanceTypes.add(instanceType);
+                    }
+
+                    getModel().getInstanceTypes().setItems(instanceTypes);
+                    for (InstanceType instanceType : instanceTypes) {
+                        if (instanceType == null && selectedInstanceTypeId == 
null) {
+                            
getModel().getInstanceTypes().setSelectedItem(null);
+                            break;
+                        }
+
+                        if (instanceType != null && selectedInstanceTypeId != 
null && instanceType.getId().equals(selectedInstanceTypeId)) {
+                            
getModel().getInstanceTypes().setSelectedItem(instanceType);
+                            break;
+                        }
+                    }
+
+                }
+            }
+        };
+
+        Frontend.getInstance().runQuery(VdcQueryType.Search, params, query);
+    }
+
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/pools/BaseVmListModelTest.java
 
b/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/pools/BaseVmListModelTest.java
index b6ced4b..1b390a4 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/pools/BaseVmListModelTest.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/pools/BaseVmListModelTest.java
@@ -3,6 +3,7 @@
 
 import org.ovirt.engine.core.common.businessentities.BootSequence;
 import org.ovirt.engine.core.common.businessentities.DisplayType;
+import org.ovirt.engine.core.common.businessentities.InstanceType;
 import org.ovirt.engine.core.common.businessentities.MigrationSupport;
 import org.ovirt.engine.core.common.businessentities.Quota;
 import org.ovirt.engine.core.common.businessentities.SsoMethod;
@@ -49,6 +50,7 @@
     protected static final String KERNEL_PATH_2 = "kernel_path2";    
//$NON-NLS-1$
     protected static final String KERNEL_PARAMS_2 = "kernel_params2";  
//$NON-NLS-1$
     protected static final String CUSTOM_PROPERTIES = "custom_properties"; 
//$NON-NLS-1$
+    protected static final Guid INSTANCE_TYPE_ID = Guid.newGuid();
     protected static final Guid QUOTA_ID = Guid.newGuid();
     protected static final String VNC_KEYBOARD_LAYOUT = "en-us"; //$NON-NLS-1$
     protected static final String VNC_KEYBOARD_LAYOUT_2 = "cz-cs"; 
//$NON-NLS-1$
@@ -67,6 +69,9 @@
         template.setId(TEMPLATE_GUID);
         when(model.getTemplate().getSelectedItem()).thenReturn(template);
         when(model.getName().getEntity()).thenReturn(VM_NAME);
+        InstanceType instanceType = new VmTemplate();
+        instanceType.setId(INSTANCE_TYPE_ID);
+        
when(model.getInstanceTypes().getSelectedItem()).thenReturn(instanceType);
         when(model.getOSType().getSelectedItem()).thenReturn(OS_TYPE);
         
when(model.getNumOfMonitors().getSelectedItem()).thenReturn(NUM_OF_MONITORS);
         when(model.getDescription().getEntity()).thenReturn(DESCRIPTION);
@@ -197,6 +202,7 @@
     protected void verifyBuiltVmSpecific(VM vm) {
         assertEquals(TEMPLATE_GUID, vm.getVmtGuid());
         assertEquals(CUSTOM_PROPERTIES, vm.getCustomProperties());
+        assertEquals(INSTANCE_TYPE_ID, vm.getInstanceTypeId());
     }
 
     protected void verifyBuiltOrigVm(VM origVm, VM vm) {


-- 
To view, visit http://gerrit.ovirt.org/24583
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id16e521a4ccde46ec967075a3c643fda254e6fde
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Tomas Jelinek <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to