Skip to content

Commit acce88f

Browse files
committed
Merge remote-tracking branch 'apache/4.19'
2 parents e817e04 + 57e67af commit acce88f

File tree

12 files changed

+100
-53
lines changed

12 files changed

+100
-53
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ public class ApiConstants {
454454
public static final String TEMPLATE_IDS = "templateids";
455455
public static final String TEMPLATE_NAME = "templatename";
456456
public static final String TEMPLATE_TYPE = "templatetype";
457+
public static final String TEMPLATE_FORMAT = "templateformat";
457458
public static final String TIMEOUT = "timeout";
458459
public static final String TIMEZONE = "timezone";
459460
public static final String TIMEZONEOFFSET = "timezoneoffset";

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
137137
@Param(description = "the type of the template for the virtual machine", since = "4.19.0")
138138
private String templateType;
139139

140+
@SerializedName(ApiConstants.TEMPLATE_FORMAT)
141+
@Param(description = "the format of the template for the virtual machine", since = "4.19.1")
142+
private String templateFormat;
143+
140144
@SerializedName("templatedisplaytext")
141145
@Param(description = " an alternate display text of the template for the virtual machine")
142146
private String templateDisplayText;
@@ -1076,6 +1080,14 @@ public void setTemplateType(String templateType) {
10761080
this.templateType = templateType;
10771081
}
10781082

1083+
public String getTemplateFormat() {
1084+
return templateFormat;
1085+
}
1086+
1087+
public void setTemplateFormat(String templateFormat) {
1088+
this.templateFormat = templateFormat;
1089+
}
1090+
10791091
public List<VnfNicResponse> getVnfNics() {
10801092
return vnfNics;
10811093
}

engine/schema/src/main/resources/META-INF/db/views/cloud.user_vm_view.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ SELECT
7474
`vm_template`.`uuid` AS `template_uuid`,
7575
`vm_template`.`name` AS `template_name`,
7676
`vm_template`.`type` AS `template_type`,
77+
`vm_template`.`format` AS `template_format`,
7778
`vm_template`.`display_text` AS `template_display_text`,
7879
`vm_template`.`enable_password` AS `password_enabled`,
7980
`iso`.`id` AS `iso_id`,

server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ public UserVmResponse newUserVmResponse(ResponseView view, String objectName, Us
197197
userVmResponse.setTemplateDisplayText(userVm.getTemplateDisplayText());
198198
userVmResponse.setPasswordEnabled(userVm.isPasswordEnabled());
199199
userVmResponse.setTemplateType(userVm.getTemplateType().toString());
200+
userVmResponse.setTemplateFormat(userVm.getTemplateFormat().toString());
200201
}
201202
if (details.contains(VMDetails.all) || details.contains(VMDetails.iso)) {
202203
userVmResponse.setIsoId(userVm.getIsoUuid());

server/src/main/java/com/cloud/api/query/vo/UserVmJoinVO.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.cloud.network.Network.GuestType;
3636
import com.cloud.network.Networks.TrafficType;
3737
import com.cloud.resource.ResourceState;
38+
import com.cloud.storage.Storage;
3839
import com.cloud.storage.Storage.TemplateType;
3940
import com.cloud.storage.Storage.StoragePoolType;
4041
import com.cloud.storage.Volume;
@@ -201,6 +202,9 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
201202
@Column(name = "template_display_text", length = 4096)
202203
private String templateDisplayText;
203204

205+
@Column(name = "template_format")
206+
private Storage.ImageFormat templateFormat;
207+
204208
@Column(name = "password_enabled")
205209
private boolean passwordEnabled;
206210

@@ -647,6 +651,10 @@ public String getTemplateDisplayText() {
647651
return templateDisplayText;
648652
}
649653

654+
public Storage.ImageFormat getTemplateFormat() {
655+
return templateFormat;
656+
}
657+
650658
public boolean isPasswordEnabled() {
651659
return passwordEnabled;
652660
}

server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ public List<? extends AutoScaleVmGroup> listAutoScaleVmGroups(ListAutoScaleVmGro
11721172
Long profileId = cmd.getProfileId();
11731173
Long zoneId = cmd.getZoneId();
11741174
Boolean forDisplay = cmd.getDisplay();
1175+
String keyword = cmd.getKeyword();
11751176

11761177
SearchWrapper<AutoScaleVmGroupVO> searchWrapper = new SearchWrapper<>(autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId());
11771178
SearchBuilder<AutoScaleVmGroupVO> sb = searchWrapper.getSearchBuilder();
@@ -1182,6 +1183,7 @@ public List<? extends AutoScaleVmGroup> listAutoScaleVmGroups(ListAutoScaleVmGro
11821183
sb.and("profileId", sb.entity().getProfileId(), SearchCriteria.Op.EQ);
11831184
sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
11841185
sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
1186+
sb.and("keyword", sb.entity().getName(), SearchCriteria.Op.LIKE);
11851187

11861188
if (policyId != null) {
11871189
SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = autoScaleVmGroupPolicyMapDao.createSearchBuilder();
@@ -1211,6 +1213,9 @@ public List<? extends AutoScaleVmGroup> listAutoScaleVmGroups(ListAutoScaleVmGro
12111213
if (forDisplay != null) {
12121214
sc.setParameters("display", forDisplay);
12131215
}
1216+
if (StringUtils.isNotBlank(keyword)) {
1217+
sc.setParameters("keyword", "%" + keyword + "%");
1218+
}
12141219
return searchWrapper.search();
12151220
}
12161221

server/src/test/java/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,12 @@
1616
// under the License.
1717
package com.cloud.api.query.dao;
1818

19-
import com.cloud.api.query.vo.UserVmJoinVO;
20-
import com.cloud.storage.Storage;
21-
import com.cloud.storage.VnfTemplateDetailVO;
22-
import com.cloud.storage.VnfTemplateNicVO;
23-
import com.cloud.storage.dao.VnfTemplateDetailsDao;
24-
import com.cloud.storage.dao.VnfTemplateNicDao;
25-
import com.cloud.user.Account;
26-
import com.cloud.user.AccountManager;
27-
import com.cloud.user.UserStatisticsVO;
28-
import com.cloud.user.dao.UserDao;
29-
import com.cloud.user.dao.UserStatisticsDao;
30-
import com.cloud.utils.db.SearchBuilder;
31-
import com.cloud.utils.db.SearchCriteria;
32-
import com.cloud.vm.dao.UserVmDetailsDao;
19+
import static org.mockito.ArgumentMatchers.nullable;
20+
import static org.mockito.MockitoAnnotations.openMocks;
21+
22+
import java.util.Arrays;
23+
import java.util.EnumSet;
24+
3325
import org.apache.cloudstack.annotation.dao.AnnotationDao;
3426
import org.apache.cloudstack.api.ApiConstants;
3527
import org.apache.cloudstack.api.ResponseObject;
@@ -44,11 +36,20 @@
4436
import org.mockito.Mockito;
4537
import org.mockito.junit.MockitoJUnitRunner;
4638

47-
import java.util.Arrays;
48-
import java.util.EnumSet;
49-
50-
import static org.mockito.ArgumentMatchers.nullable;
51-
import static org.mockito.MockitoAnnotations.openMocks;
39+
import com.cloud.api.query.vo.UserVmJoinVO;
40+
import com.cloud.storage.Storage;
41+
import com.cloud.storage.VnfTemplateDetailVO;
42+
import com.cloud.storage.VnfTemplateNicVO;
43+
import com.cloud.storage.dao.VnfTemplateDetailsDao;
44+
import com.cloud.storage.dao.VnfTemplateNicDao;
45+
import com.cloud.user.Account;
46+
import com.cloud.user.AccountManager;
47+
import com.cloud.user.UserStatisticsVO;
48+
import com.cloud.user.dao.UserDao;
49+
import com.cloud.user.dao.UserStatisticsDao;
50+
import com.cloud.utils.db.SearchBuilder;
51+
import com.cloud.utils.db.SearchCriteria;
52+
import com.cloud.vm.dao.UserVmDetailsDao;
5253

5354
@RunWith(MockitoJUnitRunner.class)
5455
public class UserVmJoinDaoImplTest extends GenericDaoBaseWithTagInformationBaseTest<UserVmJoinVO, UserVmResponse> {
@@ -113,6 +114,7 @@ private void prepareNewUserVmResponseForVnfAppliance() {
113114
Mockito.when(userVmMock.getId()).thenReturn(vmId);
114115
Mockito.when(userVmMock.getTemplateId()).thenReturn(templateId);
115116
Mockito.when(userVmMock.getTemplateType()).thenReturn(Storage.TemplateType.VNF);
117+
Mockito.when(userVmMock.getTemplateFormat()).thenReturn(Storage.ImageFormat.OVA);
116118

117119
Mockito.when(caller.getId()).thenReturn(2L);
118120
Mockito.when(accountMgr.isRootAdmin(nullable(Long.class))).thenReturn(true);

ui/src/components/view/InfoCard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@
524524
<div class="resource-detail-item__details">
525525
<resource-icon v-if="resource.icon" :image="getImage(resource.icon.base64image)" size="1x" style="margin-right: 5px"/>
526526
<SaveOutlined v-else />
527-
<router-link :to="{ path: '/template/' + resource.templateid }">{{ resource.templatedisplaytext || resource.templatename || resource.templateid }} </router-link>
527+
<router-link :to="{ path: (resource.templateformat === 'ISO' ? '/iso/' : '/template/') + resource.templateid }">{{ resource.templatedisplaytext || resource.templatename || resource.templateid }} </router-link>
528528
</div>
529529
</div>
530530
<div class="resource-detail-item" v-if="resource.isoid">

ui/src/config/section/image.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export default {
231231
}
232232
return fields
233233
},
234-
details: ['name', 'id', 'displaytext', 'checksum', 'ostypename', 'size', 'bootable', 'isready', 'passwordenabled', 'directdownload', 'isextractable', 'ispublic', 'isfeatured', 'crosszones', 'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy', 'url'],
234+
details: ['name', 'id', 'displaytext', 'checksum', 'ostypename', 'size', 'bootable', 'isready', 'passwordenabled', 'directdownload', 'isextractable', 'ispublic', 'isfeatured', 'isdynamicallyscalable', 'crosszones', 'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy', 'url'],
235235
searchFilters: () => {
236236
var filters = ['name', 'zoneid', 'tags']
237237
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {

ui/src/views/image/RegisterOrUploadIso.vue

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -227,35 +227,45 @@
227227
</a-col>
228228
</a-row>
229229

230-
<a-form-item ref="isextractable" name="isextractable">
231-
<template #label>
232-
<tooltip-label :title="$t('label.isextractable')" :tooltip="apiParams.isextractable.description"/>
233-
</template>
234-
<a-switch v-model:checked="form.isextractable" />
235-
</a-form-item>
236-
237-
<a-form-item
238-
ref="ispublic"
239-
name="ispublic"
240-
v-if="$store.getters.userInfo.roletype === 'Admin' || $store.getters.features.userpublictemplateenabled" >
241-
<template #label>
242-
<tooltip-label :title="$t('label.ispublic')" :tooltip="apiParams.ispublic.description"/>
243-
</template>
244-
<a-switch v-model:checked="form.ispublic" />
245-
</a-form-item>
246-
247-
<a-form-item ref="isfeatured" name="isfeatured" v-if="$store.getters.userInfo.roletype === 'Admin'">
248-
<template #label>
249-
<tooltip-label :title="$t('label.isfeatured')" :tooltip="apiParams.isfeatured.description"/>
250-
</template>
251-
<a-switch v-model:checked="form.isfeatured" />
252-
</a-form-item>
253-
<a-form-item ref="passwordenabled" name="passwordenabled" v-if="currentForm === 'Create'">
254-
<template #label>
255-
<tooltip-label :title="$t('label.passwordenabled')" :tooltip="apiParams.passwordenabled.description"/>
256-
</template>
257-
<a-switch v-model:checked="form.passwordenabled" />
258-
</a-form-item>
230+
<a-row :gutter="12">
231+
<a-col :md="24" :lg="12">
232+
<a-form-item ref="isdynamicallyscalable" name="isdynamicallyscalable">
233+
<template #label>
234+
<tooltip-label :title="$t('label.isdynamicallyscalable')" :tooltip="apiParams.isdynamicallyscalable.description"/>
235+
</template>
236+
<a-switch v-model:checked="form.isdynamicallyscalable" />
237+
</a-form-item>
238+
<a-form-item
239+
ref="ispublic"
240+
name="ispublic"
241+
v-if="$store.getters.userInfo.roletype === 'Admin' || $store.getters.features.userpublictemplateenabled" >
242+
<template #label>
243+
<tooltip-label :title="$t('label.ispublic')" :tooltip="apiParams.ispublic.description"/>
244+
</template>
245+
<a-switch v-model:checked="form.ispublic" />
246+
</a-form-item>
247+
<a-form-item ref="passwordenabled" name="passwordenabled" v-if="currentForm === 'Create'">
248+
<template #label>
249+
<tooltip-label :title="$t('label.passwordenabled')" :tooltip="apiParams.passwordenabled.description"/>
250+
</template>
251+
<a-switch v-model:checked="form.passwordenabled" />
252+
</a-form-item>
253+
</a-col>
254+
<a-col :md="24" :lg="12">
255+
<a-form-item ref="isextractable" name="isextractable">
256+
<template #label>
257+
<tooltip-label :title="$t('label.isextractable')" :tooltip="apiParams.isextractable.description"/>
258+
</template>
259+
<a-switch v-model:checked="form.isextractable" />
260+
</a-form-item>
261+
<a-form-item ref="isfeatured" name="isfeatured" v-if="$store.getters.userInfo.roletype === 'Admin'">
262+
<template #label>
263+
<tooltip-label :title="$t('label.isfeatured')" :tooltip="apiParams.isfeatured.description"/>
264+
</template>
265+
<a-switch v-model:checked="form.isfeatured" />
266+
</a-form-item>
267+
</a-col>
268+
</a-row>
259269

260270
<div :span="24" class="action-button">
261271
<a-button @click="closeAction">{{ $t('label.cancel') }}</a-button>
@@ -339,7 +349,8 @@ export default {
339349
bootable: true,
340350
isextractable: false,
341351
ispublic: false,
342-
passwordenabled: false
352+
passwordenabled: false,
353+
isdynamicallyscalable: false
343354
})
344355
this.rules = reactive({
345356
url: [{ required: true, message: this.$t('label.upload.iso.from.local') }],

0 commit comments

Comments
 (0)