Skip to content

Commit 5b46900

Browse files
shwstpprdhslove
authored andcommitted
ui,api,server: template categorization based on os (apache#10773)
Adds new interface for image selection (template/iso) for an instance in UI. Old interface can still be used and it can be configured using UI configuration (config.json) OS categories/Guest OS categories have been improved with ability to create new categories, delete an existing category, and marking a category as featured to allow it to show up in the UI in the image selection interface. New APIs added: - addOsCategory - deleteOsCategory - updateOsCategory APIs updated: - updateOsType - listTemplates - listOsCategories Several improvements in UI especially related to forms - DeloyVM, ReinstallVM, CreateVnfAppliance, AddAutoscaleGroup. DeployVM form can now be opened from template/ISO details view with query params. Reorganized (removed and added some) OS categories to the following (in the same order): ``` 1. Ubuntu 2. Debian 3. Fedora 4. CentOS 5. Rocky Linux 6. Alma Linux 7. Oracle 8. RedHat 9. SUSE 10. Windows 11. Other ``` Documentation PR: apache/cloudstack-documentation#500 Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 75d0334 commit 5b46900

File tree

79 files changed

+5028
-1228
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+5028
-1228
lines changed

api/src/main/java/com/cloud/event/EventTypes.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,9 @@ public class EventTypes {
693693
public static final String EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.CONFIGURE";
694694

695695
//Guest OS related events
696+
public static final String EVENT_GUEST_OS_CATEGORY_ADD = "GUEST.OS.CATEGORY.ADD";
697+
public static final String EVENT_GUEST_OS_CATEGORY_DELETE = "GUEST.OS.CATEGORY.DELETE";
698+
public static final String EVENT_GUEST_OS_CATEGORY_UPDATE = "GUEST.OS.CATEGORY.UPDATE";
696699
public static final String EVENT_GUEST_OS_ADD = "GUEST.OS.ADD";
697700
public static final String EVENT_GUEST_OS_REMOVE = "GUEST.OS.REMOVE";
698701
public static final String EVENT_GUEST_OS_UPDATE = "GUEST.OS.UPDATE";

api/src/main/java/com/cloud/server/ManagementService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@
2525
import org.apache.cloudstack.api.command.admin.config.ListCfgGroupsByCmd;
2626
import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
2727
import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
28+
import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCategoryCmd;
2829
import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
2930
import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
31+
import org.apache.cloudstack.api.command.admin.guest.DeleteGuestOsCategoryCmd;
3032
import org.apache.cloudstack.api.command.admin.guest.GetHypervisorGuestOsNamesCmd;
3133
import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
3234
import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
3335
import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
36+
import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCategoryCmd;
3437
import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCmd;
3538
import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
3639
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
@@ -185,6 +188,12 @@ public interface ManagementService {
185188
*/
186189
Pair<List<? extends GuestOsCategory>, Integer> listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd);
187190

191+
GuestOsCategory addGuestOsCategory(AddGuestOsCategoryCmd cmd);
192+
193+
GuestOsCategory updateGuestOsCategory(UpdateGuestOsCategoryCmd cmd);
194+
195+
boolean deleteGuestOsCategory(DeleteGuestOsCategoryCmd cmd);
196+
188197
/**
189198
* Obtains a list of all guest OS mappings
190199
*

api/src/main/java/com/cloud/server/ResourceIconManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
// under the License.
1717
package com.cloud.server;
1818

19+
import java.util.Collection;
1920
import java.util.List;
21+
import java.util.Map;
2022

2123
public interface ResourceIconManager {
2224

@@ -25,4 +27,8 @@ public interface ResourceIconManager {
2527
boolean deleteResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType);
2628

2729
ResourceIcon getByResourceTypeAndUuid(ResourceTag.ResourceObjectType type, String resourceId);
30+
31+
Map<Long, ResourceIcon> getByResourceTypeAndIds(ResourceTag.ResourceObjectType type, Collection<Long> resourceIds);
32+
33+
Map<String, ResourceIcon> getByResourceTypeAndUuids(ResourceTag.ResourceObjectType type, Collection<String> resourceUuids);
2834
}

api/src/main/java/com/cloud/server/ResourceTag.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public enum ResourceObjectType {
6666
LBStickinessPolicy(false, true),
6767
LBHealthCheckPolicy(false, true),
6868
SnapshotPolicy(true, true),
69+
GuestOsCategory(false, false, true),
6970
GuestOs(false, true),
7071
NetworkOffering(false, true),
7172
VpcOffering(true, false),

api/src/main/java/com/cloud/storage/GuestOsCategory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
// under the License.
1717
package com.cloud.storage;
1818

19+
import java.util.Date;
20+
1921
import org.apache.cloudstack.api.Identity;
2022
import org.apache.cloudstack.api.InternalIdentity;
2123

@@ -27,4 +29,7 @@ public interface GuestOsCategory extends Identity, InternalIdentity {
2729

2830
void setName(String name);
2931

32+
boolean isFeatured();
33+
34+
Date getCreated();
3035
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public enum ApiCommandResourceType {
6161
AffinityGroup(org.apache.cloudstack.affinity.AffinityGroup.class),
6262
InternalLbVm(com.cloud.network.router.VirtualRouter.class),
6363
DedicatedGuestVlanRange(com.cloud.network.GuestVlan.class),
64+
GuestOsCategory(com.cloud.storage.GuestOsCategory.class),
6465
GuestOs(com.cloud.storage.GuestOS.class),
6566
GuestOsMapping(com.cloud.storage.GuestOSHypervisor.class),
6667
Network(com.cloud.network.Network.class),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ public class ApiConstants {
305305
public static final String IS_EXTRACTABLE = "isextractable";
306306
public static final String IS_FEATURED = "isfeatured";
307307
public static final String IS_IMPLICIT = "isimplicit";
308+
public static final String IS_ISO = "isiso";
308309
public static final String IS_PORTABLE = "isportable";
309310
public static final String IS_PUBLIC = "ispublic";
310311
public static final String IS_PERSISTENT = "ispersistent";

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,16 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424

25-
import com.cloud.bgp.ASNumber;
26-
import com.cloud.bgp.ASNumberRange;
27-
28-
import org.apache.cloudstack.storage.object.Bucket;
2925
import org.apache.cloudstack.affinity.AffinityGroup;
3026
import org.apache.cloudstack.affinity.AffinityGroupResponse;
3127
import org.apache.cloudstack.api.ApiConstants.HostDetails;
3228
import org.apache.cloudstack.api.ApiConstants.VMDetails;
3329
import org.apache.cloudstack.api.ResponseObject.ResponseView;
3430
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
35-
import org.apache.cloudstack.api.response.AccountResponse;
36-
import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
3731
import org.apache.cloudstack.api.response.ASNRangeResponse;
3832
import org.apache.cloudstack.api.response.ASNumberResponse;
33+
import org.apache.cloudstack.api.response.AccountResponse;
34+
import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
3935
import org.apache.cloudstack.api.response.AsyncJobResponse;
4036
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
4137
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
@@ -60,10 +56,10 @@
6056
import org.apache.cloudstack.api.response.DomainRouterResponse;
6157
import org.apache.cloudstack.api.response.EventResponse;
6258
import org.apache.cloudstack.api.response.ExtractResponse;
63-
import org.apache.cloudstack.api.response.SharedFSResponse;
6459
import org.apache.cloudstack.api.response.FirewallResponse;
6560
import org.apache.cloudstack.api.response.FirewallRuleResponse;
6661
import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
62+
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
6763
import org.apache.cloudstack.api.response.GuestOSResponse;
6864
import org.apache.cloudstack.api.response.GuestOsMappingResponse;
6965
import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
@@ -73,11 +69,11 @@
7369
import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
7470
import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
7571
import org.apache.cloudstack.api.response.IPAddressResponse;
76-
import org.apache.cloudstack.api.response.IpQuarantineResponse;
7772
import org.apache.cloudstack.api.response.ImageStoreResponse;
7873
import org.apache.cloudstack.api.response.InstanceGroupResponse;
7974
import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
8075
import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
76+
import org.apache.cloudstack.api.response.IpQuarantineResponse;
8177
import org.apache.cloudstack.api.response.IsolationMethodResponse;
8278
import org.apache.cloudstack.api.response.LBHealthCheckResponse;
8379
import org.apache.cloudstack.api.response.LBStickinessResponse;
@@ -115,6 +111,7 @@
115111
import org.apache.cloudstack.api.response.SecurityGroupResponse;
116112
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
117113
import org.apache.cloudstack.api.response.ServiceResponse;
114+
import org.apache.cloudstack.api.response.SharedFSResponse;
118115
import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
119116
import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
120117
import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
@@ -159,11 +156,15 @@
159156
import org.apache.cloudstack.region.PortableIpRange;
160157
import org.apache.cloudstack.region.Region;
161158
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
162-
import org.apache.cloudstack.storage.sharedfs.SharedFS;
159+
import org.apache.cloudstack.storage.object.Bucket;
163160
import org.apache.cloudstack.storage.object.ObjectStore;
161+
import org.apache.cloudstack.storage.sharedfs.SharedFS;
164162
import org.apache.cloudstack.usage.Usage;
165163
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
164+
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
166165

166+
import com.cloud.bgp.ASNumber;
167+
import com.cloud.bgp.ASNumberRange;
167168
import com.cloud.capacity.Capacity;
168169
import com.cloud.configuration.ResourceCount;
169170
import com.cloud.configuration.ResourceLimit;
@@ -224,10 +225,11 @@
224225
import com.cloud.projects.ProjectInvitation;
225226
import com.cloud.region.ha.GlobalLoadBalancerRule;
226227
import com.cloud.resource.RollingMaintenanceManager;
227-
import com.cloud.server.ResourceTag;
228228
import com.cloud.server.ResourceIcon;
229+
import com.cloud.server.ResourceTag;
229230
import com.cloud.storage.GuestOS;
230231
import com.cloud.storage.GuestOSHypervisor;
232+
import com.cloud.storage.GuestOsCategory;
231233
import com.cloud.storage.ImageStore;
232234
import com.cloud.storage.Snapshot;
233235
import com.cloud.storage.StoragePool;
@@ -241,14 +243,13 @@
241243
import com.cloud.user.UserAccount;
242244
import com.cloud.user.UserData;
243245
import com.cloud.uservm.UserVm;
244-
import com.cloud.utils.net.Ip;
245246
import com.cloud.utils.Pair;
247+
import com.cloud.utils.net.Ip;
246248
import com.cloud.vm.InstanceGroup;
247249
import com.cloud.vm.Nic;
248250
import com.cloud.vm.NicSecondaryIp;
249251
import com.cloud.vm.VirtualMachine;
250252
import com.cloud.vm.snapshot.VMSnapshot;
251-
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
252253

253254
public interface ResponseGenerator {
254255
UserResponse createUserResponse(UserAccount user);
@@ -488,6 +489,10 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine
488489

489490
AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup);
490491

492+
GuestOSCategoryResponse createGuestOSCategoryResponse(GuestOsCategory guestOsCategory);
493+
494+
GuestOSCategoryResponse createGuestOSCategoryResponse(GuestOsCategory guestOsCategory, boolean showIcon);
495+
491496
GuestOSResponse createGuestOSResponse(GuestOS os);
492497

493498
GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
@@ -575,4 +580,6 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine
575580
BackupRepositoryResponse createBackupRepositoryResponse(BackupRepository repository);
576581

577582
SharedFSResponse createSharedFSResponse(ResponseView view, SharedFS sharedFS);
583+
584+
void updateTemplateIsoResponsesForIcons(List<TemplateResponse> responses, ResourceTag.ResourceObjectType type);
578585
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.guest;
19+
20+
import org.apache.cloudstack.acl.RoleType;
21+
import org.apache.cloudstack.api.APICommand;
22+
import org.apache.cloudstack.api.ApiCommandResourceType;
23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.ServerApiException;
28+
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
29+
30+
import com.cloud.storage.GuestOsCategory;
31+
import com.cloud.user.Account;
32+
33+
@APICommand(name = "addOsCategory",
34+
description = "Adds a new OS category",
35+
responseObject = GuestOSCategoryResponse.class,
36+
requestHasSensitiveInfo = false,
37+
responseHasSensitiveInfo = false,
38+
since = "4.21.0",
39+
authorized = {RoleType.Admin})
40+
public class AddGuestOsCategoryCmd extends BaseCmd {
41+
42+
43+
/////////////////////////////////////////////////////
44+
//////////////// API parameters /////////////////////
45+
/////////////////////////////////////////////////////
46+
47+
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the OS category",
48+
required = true)
49+
private String name;
50+
51+
@Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN,
52+
description = "Whether the category is featured or not")
53+
private Boolean featured;
54+
55+
/////////////////////////////////////////////////////
56+
/////////////////// Accessors ///////////////////////
57+
/////////////////////////////////////////////////////
58+
59+
public String getName() {
60+
return name;
61+
}
62+
63+
public boolean isFeatured() {
64+
return Boolean.TRUE.equals(featured);
65+
}
66+
67+
/////////////////////////////////////////////////////
68+
/////////////// API Implementation///////////////////
69+
/////////////////////////////////////////////////////
70+
71+
@Override
72+
public void execute() {
73+
GuestOsCategory guestOs = _mgr.addGuestOsCategory(this);
74+
if (guestOs != null) {
75+
GuestOSCategoryResponse response = _responseGenerator.createGuestOSCategoryResponse(guestOs);
76+
response.setResponseName(getCommandName());
77+
setResponseObject(response);
78+
} else {
79+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add new OS category");
80+
}
81+
82+
}
83+
84+
@Override
85+
public long getEntityOwnerId() {
86+
return Account.ACCOUNT_ID_SYSTEM;
87+
}
88+
89+
@Override
90+
public ApiCommandResourceType getApiResourceType() {
91+
return ApiCommandResourceType.GuestOsCategory;
92+
}
93+
}

0 commit comments

Comments
 (0)