|
1 | 1 | package org.zstack.compute.allocator;
|
2 | 2 |
|
3 | 3 | import org.springframework.beans.factory.annotation.Autowire;
|
| 4 | +import org.springframework.beans.factory.annotation.Autowired; |
4 | 5 | import org.springframework.beans.factory.annotation.Configurable;
|
5 |
| -import org.zstack.compute.host.HostSystemTags; |
| 6 | +import org.zstack.compute.host.HostManager; |
6 | 7 | import org.zstack.core.Platform;
|
| 8 | +import org.zstack.core.db.Q; |
7 | 9 | import org.zstack.header.allocator.AbstractHostAllocatorFlow;
|
8 |
| -import org.zstack.header.host.HostVO; |
| 10 | +import org.zstack.header.host.*; |
| 11 | +import org.zstack.header.vo.ResourceVO; |
9 | 12 |
|
10 |
| -import java.util.ArrayList; |
11 |
| -import java.util.HashMap; |
12 |
| -import java.util.List; |
13 |
| -import java.util.Map; |
| 13 | +import java.util.*; |
14 | 14 | import java.util.Map.Entry;
|
| 15 | +import java.util.stream.Collectors; |
15 | 16 |
|
16 | 17 | /**
|
| 18 | + * Filter out hosts that do not match the operating system of the specific host |
17 | 19 | */
|
18 | 20 | @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
|
19 | 21 | public class HostOsVersionAllocatorFlow extends AbstractHostAllocatorFlow {
|
| 22 | + @Autowired |
| 23 | + private HostManager manager; |
| 24 | + |
20 | 25 | @Override
|
21 | 26 | public void allocate() {
|
22 | 27 | throwExceptionIfIAmTheFirstFlow();
|
23 | 28 |
|
24 |
| - Map<String, HostVO> hostMap = new HashMap<String, HostVO>(); |
| 29 | + Map<String, HostVO> hostMap = new HashMap<>(); |
25 | 30 | for (HostVO h : candidates) {
|
26 | 31 | hostMap.put(h.getUuid(), h);
|
27 | 32 | }
|
28 | 33 |
|
29 |
| - List<String> hostUuids = new ArrayList<String>(); |
30 |
| - hostUuids.addAll(hostMap.keySet()); |
| 34 | + final String currentHostUuid = spec.getVmInstance().getHostUuid(); |
| 35 | + List<HostVO> allHostList = new ArrayList<>(candidates); |
| 36 | + final HostVO currentHost = Q.New(HostVO.class) |
| 37 | + .eq(HostVO_.uuid, currentHostUuid) |
| 38 | + .find(); |
| 39 | + allHostList.add(currentHost); |
| 40 | + Map<String, HostOperationSystem> hostOsMap = generateHostUuidOsMap(allHostList); |
31 | 41 |
|
32 |
| - String distro = HostSystemTags.OS_DISTRIBUTION.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_DISTRIBUTION_TOKEN); |
33 |
| - String release = HostSystemTags.OS_RELEASE.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_RELEASE_TOKEN); |
34 |
| - String version = HostSystemTags.OS_VERSION.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_VERSION_TOKEN); |
35 |
| - String currentVersion = String.format("%s;%s;%s", distro, release, version); |
| 42 | + final HostOperationSystem currentHostOs = hostOsMap.get(currentHostUuid); |
| 43 | + hostOsMap.remove(currentHostUuid); |
36 | 44 |
|
37 |
| - Map<String, List<String>> distroMap = HostSystemTags.OS_DISTRIBUTION.getTags(hostUuids); |
38 |
| - Map<String, List<String>> releaseMap = HostSystemTags.OS_RELEASE.getTags(hostUuids); |
39 |
| - Map<String, List<String>> versionMap = HostSystemTags.OS_VERSION.getTags(hostUuids); |
| 45 | + List<HostVO> matchedHosts = hostOsMap.entrySet().stream() |
| 46 | + .filter(entry -> currentHostOs.equals(entry.getValue())) |
| 47 | + .map(Entry::getKey) |
| 48 | + .map(hostMap::get) |
| 49 | + .collect(Collectors.toList()); |
40 | 50 |
|
41 |
| - Map<String, String> candidateVersions = new HashMap<String, String>(); |
42 |
| - for (String huuid : hostUuids) { |
43 |
| - List<String> ds = distroMap.get(huuid); |
44 |
| - String d = ds == null ? null : HostSystemTags.OS_DISTRIBUTION.getTokenByTag(ds.get(0), HostSystemTags.OS_DISTRIBUTION_TOKEN); |
45 |
| - List<String> rs = releaseMap.get(huuid); |
46 |
| - String r = rs == null ? null : HostSystemTags.OS_RELEASE.getTokenByTag(rs.get(0), HostSystemTags.OS_RELEASE_TOKEN); |
47 |
| - List<String> vs = versionMap.get(huuid); |
48 |
| - String v = vs == null ? null : HostSystemTags.OS_VERSION.getTokenByTag(vs.get(0), HostSystemTags.OS_VERSION_TOKEN); |
49 |
| - candidateVersions.put(huuid, String.format("%s;%s;%s", d, r, v)); |
| 51 | + if (matchedHosts.isEmpty()) { |
| 52 | + fail(Platform.operr("no candidate host has version[%s]", currentHostOs)); |
| 53 | + } else { |
| 54 | + next(matchedHosts); |
50 | 55 | }
|
| 56 | + } |
51 | 57 |
|
52 |
| - List<HostVO> ret = new ArrayList<HostVO>(); |
53 |
| - for (Entry<String, String> e : candidateVersions.entrySet()) { |
54 |
| - String huuid = e.getKey(); |
55 |
| - String ver = e.getValue(); |
56 |
| - if (ver.equals(currentVersion)) { |
57 |
| - ret.add(hostMap.get(huuid)); |
58 |
| - } |
59 |
| - } |
| 58 | + private Map<String, HostOperationSystem> generateHostUuidOsMap(List<HostVO> hostList) { |
| 59 | + final Map<String, String> hostHypervisorTypeMap = hostList.stream() |
| 60 | + .collect(Collectors.toMap(ResourceVO::getUuid, HostAO::getHypervisorType)); |
| 61 | + final Set<String> hypervisorTypeSet = new HashSet<>(hostHypervisorTypeMap.values()); |
60 | 62 |
|
61 |
| - if (ret.isEmpty()) { |
62 |
| - fail(Platform.operr("no candidate host has version[%s]", currentVersion)); |
63 |
| - } else { |
64 |
| - next(ret); |
| 63 | + final Map<String, HostOperationSystem> results = new HashMap<>(hostList.size()); |
| 64 | + for (String hypervisorTypeString : hypervisorTypeSet) { |
| 65 | + final HypervisorFactory factory = manager.getHypervisorFactory( |
| 66 | + HypervisorType.valueOf(hypervisorTypeString)); |
| 67 | + final List<String> hostsWithThisHypervisorType = hostHypervisorTypeMap.entrySet().stream() |
| 68 | + .filter(entry -> hypervisorTypeString.equals(entry.getValue())) |
| 69 | + .map(Entry::getKey) |
| 70 | + .collect(Collectors.toList()); |
| 71 | + results.putAll(factory.getHostOsMap(hostsWithThisHypervisorType)); |
65 | 72 | }
|
| 73 | + |
| 74 | + return results; |
66 | 75 | }
|
67 | 76 | }
|
0 commit comments