1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 | commit 1f7e87c2996d6a3af23e0226cc5d64b0a9106584 (smoser/feature/enable-aliyun, feature/enable-aliyun)
Author: Scott Moser <smoser@brickies.net>
Date: Thu May 25 11:55:24 2017 -0400
add ds-identify unit test for aliyun
commit c337e889dce538d599f755204c790898716c3a6b
Author: Scott Moser <smoser@brickies.net>
Date: Thu May 25 09:45:05 2017 -0400
A few more changes.
- add the Platforms.NO_EC2_MD
this allows the AliYun cloud_platform property to set the value
of cloud_platform to either NO_EC2_MD or Platforms.ALIYUN.
Also, modify the superclasses' get_data to recognize NO_EC2_MD
specifically to return "not found". Without this, if strict was warn
or false, then the aliyun datasource would be used. This way, aliyun
effecitvely doesn't use the strict_mode.
- enable aliyun datasource by default.
update tools/ds-identify to
a.) know that AliYun is enabled by default.
b.) search for the AliYun datasource by dmi product id.
commit b04d4fecd14108f05ce076597b30b8495411979f
Author: Junjie Wang <jingni.wjj@alibaba-inc.com>
Date: Fri Apr 21 20:06:09 2017 +0800
AliYun: Enable platform identification and enable by default.
AliYun cloud platform is now identifying themselves by setting the dmi
product id to the well known value "Alibaba Cloud ECS". The changes here
identify that properly in tools/ds-identify and in the DataSourceAliYun.
Since the 'get_data' for AliYun now identifies itself correctly, we can
enable AliYun by default.
LP: #1638931
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index 411960d8..17697cfa 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -20,6 +20,7 @@ RUN_CLOUD_CONFIG = '/run/cloud-init/cloud.cfg'
CFG_BUILTIN = {
'datasource_list': [
'NoCloud',
+ 'AliYun',
'ConfigDrive',
'OpenNebula',
'DigitalOcean',
diff --git a/cloudinit/sources/DataSourceAliYun.py b/cloudinit/sources/DataSourceAliYun.py
index 9debe947..b511256c 100644
--- a/cloudinit/sources/DataSourceAliYun.py
+++ b/cloudinit/sources/DataSourceAliYun.py
@@ -4,8 +4,10 @@ import os
from cloudinit import sources
from cloudinit.sources import DataSourceEc2 as EC2
+from cloudinit import util
DEF_MD_VERSION = "2016-01-01"
+ALIYUN_PRODUCT = "Alibaba Cloud ECS"
class DataSourceAliYun(EC2.DataSourceEc2):
@@ -24,7 +26,17 @@ class DataSourceAliYun(EC2.DataSourceEc2):
@property
def cloud_platform(self):
- return EC2.Platforms.ALIYUN
+ if self._cloud_platform is None:
+ if _is_aliyun():
+ self._cloud_platform = EC2.Platforms.ALIYUN
+ else:
+ self._cloud_platform = EC2.Platforms.NO_EC2_MD
+
+ return self._cloud_platform
+
+
+def _is_aliyun():
+ return util.read_dmi_data('system-product-name') == ALIYUN_PRODUCT
def parse_public_keys(public_keys):
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
index 2f9c7edf..ecd08c7f 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -33,6 +33,7 @@ class Platforms(object):
BRIGHTBOX = "Brightbox"
SEEDED = "Seeded"
UNKNOWN = "Unknown"
+ NO_EC2_MD = "No-EC2-Metadata"
class DataSourceEc2(sources.DataSource):
@@ -65,6 +66,8 @@ class DataSourceEc2(sources.DataSource):
strict_mode, self.cloud_platform)
if strict_mode == "true" and self.cloud_platform == Platforms.UNKNOWN:
return False
+ elif self.cloud_platform == Platforms.NO_EC2_MD:
+ return False
try:
if not self.wait_for_metadata_service():
diff --git a/tests/unittests/test_datasource/test_aliyun.py b/tests/unittests/test_datasource/test_aliyun.py
index c16d1a6e..b42187f4 100644
--- a/tests/unittests/test_datasource/test_aliyun.py
+++ b/tests/unittests/test_datasource/test_aliyun.py
@@ -2,6 +2,7 @@
import functools
import httpretty
+import mock
import os
from .. import helpers as test_helpers
@@ -111,8 +112,10 @@ class TestAliYunDatasource(test_helpers.HttprettyTestCase):
self.assertEqual(self.default_metadata['hostname'],
self.ds.get_hostname())
+ @mock.patch("cloudinit.sources.DataSourceAliYun._is_aliyun")
@httpretty.activate
- def test_with_mock_server(self):
+ def test_with_mock_server(self, m_is_aliyun):
+ m_is_aliyun.return_value = True
self.regist_default_server()
self.ds.get_data()
self._test_get_data()
diff --git a/tests/unittests/test_datasource/test_common.py b/tests/unittests/test_datasource/test_common.py
index c08717f3..7649b9ae 100644
--- a/tests/unittests/test_datasource/test_common.py
+++ b/tests/unittests/test_datasource/test_common.py
@@ -36,6 +36,7 @@ DEFAULT_LOCAL = [
]
DEFAULT_NETWORK = [
+ AliYun.DataSourceAliYun,
AltCloud.DataSourceAltCloud,
Azure.DataSourceAzureNet,
Bigstep.DataSourceBigstep,
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
index f5694b26..5c26e65f 100644
--- a/tests/unittests/test_ds_identify.py
+++ b/tests/unittests/test_ds_identify.py
@@ -220,6 +220,20 @@ class TestDsIdentify(CiTestCase):
mydata['files'][cfgpath] = 'datasource_list: ["Ec2", "None"]\n'
self._check_via_dict(mydata, rc=RC_FOUND, dslist=['Ec2', DS_NONE])
+ def test_aliyun_identified(self):
+ """Test that Aliyun cloud is identified by product id."""
+ self._test_ds_found('AliYun')
+
+ def test_aliyun_over_ec2(self):
+ """Even if all other factors identified Ec2, AliYun should be used."""
+ mydata = copy.deepcopy(VALID_CFG['Ec2-xen'])
+ self._test_ds_found('AliYun')
+ prod_name = VALID_CFG['AliYun']['files'][P_PRODUCT_NAME]
+ mydata['files'][P_PRODUCT_NAME] = prod_name
+ policy = "search,found=first,maybe=none,notfound=disabled"
+ self._check_via_dict(mydata, rc=RC_FOUND, dslist=['AliYun', DS_NONE],
+ policy_dmi=policy)
+
def blkid_out(disks=None):
"""Convert a list of disk dictionaries into blkid content."""
@@ -254,6 +268,10 @@ def _print_run_output(rc, out, err, cfg, files):
VALID_CFG = {
+ 'AliYun': {
+ 'ds': 'AliYun',
+ 'files': {P_PRODUCT_NAME: 'Alibaba Cloud ECS\n'},
+ },
'Ec2-hvm': {
'ds': 'Ec2',
'mocks': [{'name': 'detect_virt', 'RET': 'kvm', 'ret': 0}],
diff --git a/tools/ds-identify b/tools/ds-identify
index 74d26537..5fc500b9 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -110,7 +110,8 @@ DI_DSNAME=""
# this has to match the builtin list in cloud-init, it is what will
# be searched if there is no setting found in config.
DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \
-CloudSigma CloudStack DigitalOcean Ec2 GCE OpenNebula OpenStack OVF SmartOS"
+CloudSigma CloudStack DigitalOcean AliYun Ec2 GCE OpenNebula OpenStack \
+OVF SmartOS"
DI_DSLIST=""
DI_MODE=""
DI_ON_FOUND=""
@@ -821,10 +822,11 @@ dscheck_OpenStack() {
}
dscheck_AliYun() {
- # aliyun is not enabled by default (LP: #1638931)
- # so if we are here, it is because the datasource_list was
- # set to include it. Thus, 'maybe'.
- return $DS_MAYBE
+ check_seed_dir "AliYun" meta-data user-data && return ${DS_FOUND}
+ if dmi_product_name_is "Alibaba Cloud ECS"; then
+ return $DS_FOUND
+ fi
+ return $DS_NOT_FOUND
}
dscheck_AltCloud() {
|