Compare commits

...

471 Commits

Author SHA1 Message Date
yunion-ci-robot
40b8dfc553 Merge pull request #2526 from ioito/automated-cherry-pick-of-#2522-upstream-release-2.9.0
Automated cherry pick of #2522: fix: sync status after guest sync conf
2019-08-23 18:04:09 +08:00
ioito
3758f68d19 fix: sync status after guest sync conf 2019-08-23 17:21:25 +08:00
yunion-ci-robot
f27041df09 Merge pull request #2505 from ioito/automated-cherry-pick-of-#2499-upstream-release-2.9.0
Automated cherry pick of #2499: fix: qcloud sync unavailable storages
2019-08-23 10:56:08 +08:00
ioito
8354dbb8f5 fix: qcloud sync unavailable storages 2019-08-22 20:48:22 +08:00
yunion-ci-robot
ff805ff6c8 Merge pull request #2481 from ioito/automated-cherry-pick-of-#2451-upstream-release-2.9.0
Automated cherry pick of #2451: bugfix: 避免openstack磁盘扩容成功后未能挂载到虚拟机上
2019-08-22 11:40:07 +08:00
ioito
b3fa0b209f bugfix: 避免openstack磁盘扩容成功后未能挂载到虚拟机上 2019-08-22 10:20:33 +08:00
yunion-ci-robot
95a22c92b0 Merge pull request #2399 from ioito/automated-cherry-pick-of-#2381-upstream-release-2.9.0
Automated cherry pick of #2381: fix: httputils show error when resp body is not dict
2019-08-20 10:25:09 +08:00
ioito
e85fe5c7fd fix: httputils show error when resp body is not dict 2019-08-20 10:19:56 +08:00
yunion-ci-robot
c95ab12f39 Merge pull request #2347 from yousong/automated-cherry-pick-of-#2343-upstream-release-2.9.0
Automated cherry pick of #2343: hostman: windows: 改正批处理代码
2019-08-17 09:58:06 +08:00
Yousong Zhou
f8ab2a7f7a hostman: windows: 改正批处理代码 2019-08-16 13:22:25 +00:00
yunion-ci-robot
b1d2b5589f Merge pull request #2330 from ioito/automated-cherry-pick-of-#2326-upstream-release-2.9.0
Automated cherry pick of #2326: fix: azure快照的磁盘id应该小写
2019-08-16 16:28:04 +08:00
ioito
d0720f6c9b fix: azure快照的磁盘id应该小写 2019-08-16 15:58:57 +08:00
yunion-ci-robot
12d9e760a5 Merge pull request #2320 from ioito/automated-cherry-pick-of-#2316-upstream-release-2.9.0
Automated cherry pick of #2316: fix: create disk with project-src=local
2019-08-16 15:22:06 +08:00
ioito
5ea6136852 fix: create disk with project-src=local 2019-08-16 15:06:43 +08:00
yunion-ci-robot
303c92ce61 Merge pull request #2255 from wanyaoqi/automated-cherry-pick-of-#2250-upstream-release-2.9.0
Automated cherry pick of #2250: support get user tags
2019-08-13 18:55:03 +08:00
wanyaoqi
f94607c222 support get user tags 2019-08-13 18:40:39 +08:00
yunion-ci-robot
efaa3fed87 Merge pull request #2237 from ioito/automated-cherry-pick-of-#2234-upstream-release-2.9.0
Automated cherry pick of #2234: fix: no need to inject password by cloud-init for qcloud
2019-08-12 22:17:06 +08:00
ioito
30019cebb8 fix: no need to inject password by cloud-init for qcloud 2019-08-12 20:28:16 +08:00
yunion-ci-robot
974ec2ad2e Merge pull request #2205 from ioito/automated-cherry-pick-of-#2202-upstream-release-2.9.0
Automated cherry pick of #2202: fix: sync cloud snapshot size
2019-08-12 11:50:00 +08:00
ioito
8483d2e134 fix: sync cloud snapshot size 2019-08-10 16:35:20 +08:00
yunion-ci-robot
e5abafd7be Merge pull request #2189 from ioito/automated-cherry-pick-of-#2186-upstream-release-2.9.0
Automated cherry pick of #2186: fix: lb purge error
2019-08-08 20:06:58 +08:00
ioito
22a2d4f719 fix: lb purge error 2019-08-08 19:56:57 +08:00
yunion-ci-robot
9a32881520 Merge pull request #2184 from tb365/automated-cherry-pick-of-#2181-upstream-release-2.9.0
Automated cherry pick of #2181: cpu core bugfix
2019-08-08 19:50:59 +08:00
TangBin
de1a73c660 cpu core bugfix 2019-08-08 19:42:27 +08:00
yunion-ci-robot
25cd0a4572 Merge pull request #2085 from ioito/automated-cherry-pick-of-#2082-upstream-release-2.9.0
Automated cherry pick of #2082: fix: get openstack all customize storage type
2019-08-02 20:16:05 +08:00
ioito
21a2e680fe fix: get openstack all customize storage type 2019-08-02 20:11:06 +08:00
yunion-ci-robot
395c19ff75 Merge pull request #2052 from ioito/automated-cherry-pick-of-#2048-upstream-release-2.9.0
Automated cherry pick of #2048: fix: openstack glance image-list not list all images
2019-08-01 16:54:01 +08:00
ioito
a160c0088d fix: openstack glance image-list not list all images 2019-07-31 19:45:02 +08:00
yunion-ci-robot
ca66466e9a Merge pull request #2022 from ioito/automated-cherry-pick-of-#1982-upstream-release-2.9.0
Automated cherry pick of #1982: fix: rbd image resize not found error
2019-07-31 15:55:01 +08:00
yunion-ci-robot
3301697fd0 Merge pull request #2046 from wanyaoqi/automated-cherry-pick-of-#2043-upstream-release-2.9.0
Automated cherry pick of #2043: guest export keys add zone
2019-07-31 15:51:01 +08:00
wanyaoqi
b00f61c251 guest export keys add zone 2019-07-31 15:44:52 +08:00
ioito
e834d26013 fix: rbd image resize not found error 2019-07-30 19:11:21 +08:00
yunion-ci-robot
9c5ee15ac2 Merge pull request #2008 from ioito/automated-cherry-pick-of-#2005-upstream-release-2.9.0
Automated cherry pick of #2005: fix: add priority for openstack secgroup rule priority
2019-07-30 12:56:33 +08:00
yunion-ci-robot
56450f7515 Merge pull request #1992 from ioito/automated-cherry-pick-of-#1989-upstream-release-2.9.0
Automated cherry pick of #1989: fix: qcloud reserved first, second and last ip for internal connection
2019-07-30 12:28:31 +08:00
ioito
6abb1df37e fix: add priority for openstack secgroup rule priority 2019-07-30 11:51:00 +08:00
ioito
68fa7f8c54 fix: qcloud reserved first, second and last ip for internal connection 2019-07-29 20:04:15 +08:00
yunion-ci-robot
b0e3461cff Merge pull request #1913 from ioito/automated-cherry-pick-of-#1910-upstream-release-2.9.0
Automated cherry pick of #1910: fix: 避免镜像同步到私有云自定义镜像里面
2019-07-26 15:31:08 +08:00
ioito
3840d889d4 fix: 避免镜像同步到私有云自定义镜像里面 2019-07-25 14:41:09 +08:00
yunion-ci-robot
e8bbf80674 Merge pull request #1865 from ioito/automated-cherry-pick-of-#1860-upstream-release-2.9.0
Automated cherry pick of #1860: 添加同步安全组日志
2019-07-24 09:36:08 +08:00
ioito
1d9a3c9569 避免重复设置同一vpc底下不同安全组externalId 2019-07-23 21:55:15 +08:00
ioito
7bfe1defa2 添加同步安全组日志 2019-07-23 21:55:15 +08:00
yunion-ci-robot
8b5d44c3a0 Merge pull request #1848 from ioito/automated-cherry-pick-of-#1829-upstream-release-2.9.0
Automated cherry pick of #1829: 避免cacheimage refresh时同步azure镜像信息异常
2019-07-23 18:43:05 +08:00
ioito
62363bfe93 避免cacheimage refresh时同步azure镜像信息异常 2019-07-23 15:06:38 +08:00
yunion-ci-robot
0d3b417c26 Merge pull request #1835 from ioito/automated-cherry-pick-of-#1832-upstream-release-2.9.0
Automated cherry pick of #1832: 避免因cloudprovider disable导致账号同步失效
2019-07-23 12:03:06 +08:00
yunion-ci-robot
fc1c6c18c8 Merge pull request #1827 from ioito/automated-cherry-pick-of-#1820-upstream-release-2.9.0
Automated cherry pick of #1820: 仅忽略 no such service错误,否则以最新api结果为准
2019-07-23 11:59:05 +08:00
ioito
51a0dacb2f 避免因cloudprovider disable导致账号同步失效 2019-07-22 20:05:18 +08:00
ioito
554fbcb9ee 仅忽略 no such service错误,否则以最新api结果为准 2019-07-22 10:12:05 +08:00
yunion-ci-robot
1e32948c7f Merge pull request #1799 from ioito/automated-cherry-pick-of-#1796-upstream-release-2.9.0
Automated cherry pick of #1796: 提高openstack创建windows机器成功率
2019-07-18 15:39:00 +08:00
ioito
c0b78b1b2f 提高openstack创建windows机器成功率 2019-07-18 15:06:50 +08:00
yunion-ci-robot
2b97371b49 Merge pull request #1727 from ioito/automated-cherry-pick-of-#1724-upstream-release-2.9.0
Automated cherry pick of #1724: 修复purge backend野指针引用问题
2019-07-15 10:36:57 +08:00
ioito
e33befc386 修复purge backend野指针引用问题 2019-07-15 10:24:41 +08:00
yunion-ci-robot
fec7e2006e Merge pull request #1712 from ioito/automated-cherry-pick-of-#1709-upstream-release-2.9.0
Automated cherry pick of #1709: fix console log
2019-07-13 17:39:00 +08:00
ioito
d209472435 fix console log 2019-07-13 14:47:46 +08:00
yunion-ci-robot
96cb87faee Merge pull request #1702 from ioito/automated-cherry-pick-of-#1699-upstream-release-2.9.0
Automated cherry pick of #1699: 同优先级规则deny优先于allow规则生效
2019-07-12 12:06:57 +08:00
ioito
a203e5d507 同优先级规则deny优先于allow规则生效 2019-07-12 11:55:33 +08:00
yunion-ci-robot
4c90a1af8b Merge pull request #1684 from ioito/automated-cherry-pick-of-#1681-upstream-release-2.9.0
Automated cherry pick of #1681: 宿主机存储利用率仅计算本地存储
2019-07-12 09:07:57 +08:00
yunion-ci-robot
e546d7993f Merge pull request #1679 from ioito/automated-cherry-pick-of-#1676-upstream-release-2.9.0
Automated cherry pick of #1676: 避免重装系统时绑定秘钥后没有account信息
2019-07-11 18:30:58 +08:00
ioito
795e5b4bc0 宿主机存储利用率仅计算本地存储 2019-07-11 17:30:41 +08:00
ioito
2c95828870 避免重装系统时绑定秘钥后没有account信息 2019-07-11 17:00:36 +08:00
yunion-ci-robot
31befeba6d Merge pull request #1669 from swordqiu/automated-cherry-pick-of-#1667-upstream-release-2.9.0
Automated cherry pick of #1667: fix: task usercred should be utf8 charset
2019-07-11 12:17:56 +08:00
Qiu Jian
d886e39c34 fix: bacport variable name change 2019-07-11 12:11:44 +08:00
Qiu Jian
07257f3161 fix: task usercred should be utf8 charset 2019-07-11 12:11:06 +08:00
yunion-ci-robot
2362c8bd45 Merge pull request #1657 from ioito/automated-cherry-pick-of-#1654-upstream-release-2.9.0
Automated cherry pick of #1654: fix qcloud associate eip timeout after bind
2019-07-11 08:45:56 +08:00
ioito
f0275f1da7 fix qcloud associate eip timeout after bind 2019-07-10 21:14:49 +08:00
yunion-ci-robot
6520b73231 Merge pull request #1644 from ioito/automated-cherry-pick-of-#1641-upstream-release-2.9.0
Automated cherry pick of #1641: 统一处理ResourceNotFound返回id not find
2019-07-10 20:45:56 +08:00
ioito
ad938e80de 统一处理ResourceNotFound返回id not find 2019-07-10 16:12:29 +08:00
yunion-ci-robot
073d1f25a8 Merge pull request #1629 from ioito/automated-cherry-pick-of-#1626-upstream-release-2.9.0
Automated cherry pick of #1626: metadata permission
2019-07-09 23:23:57 +08:00
yunion-ci-robot
8ea0816fbf Merge pull request #1633 from ioito/automated-cherry-pick-of-#1622-upstream-release-2.9.0
Automated cherry pick of #1622: 兼容zone及usable参数
2019-07-09 23:03:01 +08:00
ioito
8e77c4927b 兼容zone及usable参数 2019-07-09 22:46:22 +08:00
ioito
8f2267d9cb metadata permission 2019-07-09 22:39:20 +08:00
yunion-ci-robot
5e8b257b44 Merge pull request #1608 from ioito/automated-cherry-pick-of-#1602-upstream-release-2.9.0
Automated cherry pick of #1602: add task failed code
2019-07-09 17:29:58 +08:00
yunion-ci-robot
76a3f98f59 Merge pull request #1612 from ioito/automated-cherry-pick-of-#1605-upstream-release-2.9.0
Automated cherry pick of #1605: fix clone rbd image error
2019-07-09 17:22:58 +08:00
ioito
0c55ccff3b fix clone rbd image error 2019-07-09 15:50:02 +08:00
ioito
e96be122d7 add task failed code 2019-07-09 15:46:15 +08:00
yunion-ci-robot
8ebed30dc1 Merge pull request #1576 from ioito/automated-cherry-pick-of-#1573-upstream-release-2.9.0
Automated cherry pick of #1573: add usable filter for network
2019-07-05 23:03:56 +08:00
yunion-ci-robot
deea8bef4f Merge pull request #1579 from ioito/automated-cherry-pick-of-#1551-upstream-release-2.9.0
Automated cherry pick of #1551: add without_user_meta filter
2019-07-05 22:46:54 +08:00
yunion-ci-robot
6062af7f10 Merge pull request #1566 from ioito/automated-cherry-pick-of-#1563-upstream-release-2.9.0
Automated cherry pick of #1563: add deploy failed action log
2019-07-05 22:30:07 +08:00
yunion-ci-robot
8373cd2767 Merge pull request #1557 from ioito/automated-cherry-pick-of-#1550-upstream-release-2.9.0
Automated cherry pick of #1550: fix purge aliyun account error by lbbg
2019-07-05 22:21:59 +08:00
ioito
209c46f9ae optimized tag filter 2019-07-05 22:03:52 +08:00
ioito
44add5907f add without_user_meta filter 2019-07-05 21:24:40 +08:00
ioito
ca76c9c308 add usable filter for network 2019-07-05 18:50:39 +08:00
ioito
b9d08a351f add deploy failed action log 2019-07-05 14:19:47 +08:00
ioito
9963392231 fix purge aliyun account error by lbbg 2019-07-05 10:11:03 +08:00
yunion-ci-robot
5f91f89ffb Merge pull request #1532 from ioito/automated-cherry-pick-of-#1529-upstream-release-2.9.0
Automated cherry pick of #1529: fix create image with userCred issue
2019-07-03 23:24:54 +08:00
yunion-ci-robot
4ee40ff2b5 Merge pull request #1527 from ioito/automated-cherry-pick-of-#1524-upstream-release-2.9.0
Automated cherry pick of #1524: fix azure reserved ips
2019-07-03 23:18:52 +08:00
ioito
46245b0449 fix create image with userCred issue 2019-07-03 20:58:35 +08:00
ioito
fba965daa9 fix azure reserved ips 2019-07-03 20:12:40 +08:00
yunion-ci-robot
a85da7bf99 Merge pull request #1515 from wanyaoqi/bugfix/wyq/fix-image-request-timeout
cherrypick: fix image request timeout
2019-07-03 18:07:55 +08:00
wanyaoqi
9bbe702841 fix request image timeout 2019-07-03 17:59:25 +08:00
yunion-ci-robot
a143a24fc6 Merge pull request #1482 from ioito/automated-cherry-pick-of-#1479-upstream-release-2.9.0
Automated cherry pick of #1479: fix sync openstack hoststorages issue
2019-07-03 08:56:52 +08:00
yunion-ci-robot
d8c8a4b708 Merge pull request #1493 from ioito/automated-cherry-pick-of-#1486-upstream-release-2.9.0
Automated cherry pick of #1486: fix azure set secgroup error
2019-07-03 08:28:52 +08:00
yunion-ci-robot
1f5d13d3bd Merge pull request #1498 from wanyaoqi/automated-cherry-pick-of-#1495-upstream-release-2.9.0
Automated cherry pick of #1495: fix export data
2019-07-02 22:10:52 +08:00
wanyaoqi
784b06036b fix export data 2019-07-02 22:05:15 +08:00
ioito
bb1e7f1ae2 fix azure set secgroup error 2019-07-02 21:25:02 +08:00
ioito
03a68cb926 fix sync openstack hoststorages issue 2019-07-02 20:12:50 +08:00
yunion-ci-robot
f4390241e2 Merge pull request #1477 from wanyaoqi/automated-cherry-pick-of-#1471-upstream-release-2.9.0
Automated cherry pick of #1471: fix export data, set no limit; expand timeout
2019-07-02 18:50:55 +08:00
wanyaoqi
7a325ad58e fix export data, set no limit; expand timeout 2019-07-02 18:10:38 +08:00
yunion-ci-robot
28954d781b Merge pull request #1469 from ioito/automated-cherry-pick-of-#1467-upstream-release-2.9.0
Automated cherry pick of #1467: fix create disk scheduler failed
2019-07-02 16:50:53 +08:00
ioito
cfe7f3638d fix create disk scheduler failed 2019-07-02 16:46:11 +08:00
yunion-ci-robot
200fef70a6 Merge pull request #1447 from ioito/automated-cherry-pick-of-#1420-upstream-release-2.9.0
Automated cherry pick of #1420: remove keypair info if rebuild-root net set keypair
2019-07-01 11:19:51 +08:00
ioito
3d66ca1cba remove keypair info if rebuild-root net set keypair 2019-07-01 10:30:13 +08:00
yunion-ci-robot
9e419c55a2 Merge pull request #1429 from yousong/automated-cherry-pick-of-#1421-release-2.9.0
Automated cherry pick of #1421: httperrors: 支持从msgTmpl转换为带%s的msgFmt
2019-06-29 14:31:51 +08:00
Yousong Zhou
8578b59020 validators: errors: 使用msgFmt而非包含{NN}的msgTmpl 2019-06-29 06:27:58 +00:00
Yousong Zhou
a0df67ad59 httperrors: 支持从msgTmpl转换为带%s的msgFmt 2019-06-29 06:27:58 +00:00
yunion-ci-robot
4b5eed1142 Merge pull request #1402 from yousong/automated-cherry-pick-of-#1400-release-2.9.0
Automated cherry pick of #1400: lbagent: 启动时全量取API数据
2019-06-27 17:20:54 +08:00
yunion-ci-robot
06d12af977 Merge pull request #1398 from ioito/automated-cherry-pick-of-#1396-upstream-release-2.9.0
Automated cherry pick of #1396: wait ready or running after change vm config
2019-06-27 17:17:51 +08:00
yunion-ci-robot
a91511b27c Merge pull request #1395 from wanyaoqi/feature/wyq/live-migrate-filter-cpu-model-cherrypick-2.9
Manual CherryPick: live migrate filter by cpu model and mircocode, fix guest backup sta...
2019-06-27 17:01:52 +08:00
yunion-ci-robot
d64ddd76b7 Merge pull request #1409 from yousong/automated-cherry-pick-of-#670-release-2.9.0
Automated cherry pick of #670: atexit: 添加用于记录在进程退出时执行的队列
2019-06-26 22:09:49 +08:00
Yousong Zhou
ecb8429571 cloudcommon: 添加--log-file-prefix选项
指定日志文件名,rotate 10,每个100MB
2019-06-26 14:05:15 +00:00
Yousong Zhou
842840a391 atexit: 添加用于记录在进程退出时执行的队列 2019-06-26 14:04:27 +00:00
Yousong Zhou
fd7f4fb9ef lbagent: 启动时全量取API数据
此变更之后,data/目录内容更多服务于调试作用
2019-06-26 12:26:15 +00:00
ioito
f38209ea4e wait ready or running after change vm config 2019-06-26 19:33:24 +08:00
wanyaoqi
d53b548f91 live migrate filter by cpu model and mircocode, fix guest backup status, misc bugfix 2019-06-26 13:32:46 +08:00
yunion-ci-robot
87fd14dc2e Merge pull request #1391 from wanyaoqi/automated-cherry-pick-of-#1174-upstream-release-2.9.0
Automated cherry pick of #1174: import running libvirt guests
2019-06-26 12:40:50 +08:00
wanyaoqi
87c8370e29 import running libvirt guests 2019-06-26 11:20:45 +08:00
yunion-ci-robot
1a8c5729d5 Merge pull request #1374 from wanyaoqi/automated-cherry-pick-of-#1357-upstream-release-2.9.0
Automated cherry pick of #1357: set default http client timeout
2019-06-25 23:27:02 +08:00
yunion-ci-robot
07b7dea25c Merge pull request #1382 from ioito/automated-cherry-pick-of-#1380-upstream-release-2.9.0
Automated cherry pick of #1380: clear scheduler cache afeter change host cmtbound
2019-06-25 23:15:55 +08:00
ioito
620c149dd6 clear scheduler cache afeter change host cmtbound 2019-06-25 21:01:25 +08:00
wanyaoqi
c49de843e6 set default http client timeout 2019-06-25 15:38:05 +08:00
yunion-ci-robot
2695abf1fa Merge pull request #1369 from yousong/automated-cherry-pick-of-#1367-release-2.9.0
Automated cherry pick of #1367: lbagents: 改正vrrp模板
2019-06-25 11:45:51 +08:00
Yousong Zhou
a09f7e5536 validators: 默认将pending deleted的模型排除在外 2019-06-25 02:44:04 +00:00
Yousong Zhou
1d7bcc43a5 db: 添加IPendingDeletable类型 2019-06-25 02:41:18 +00:00
Yousong Zhou
f8b6cc3447 lbagents: 改正vrrp模板 2019-06-25 02:40:37 +00:00
yunion-ci-robot
16459a1acc Merge pull request #1354 from ioito/automated-cherry-pick-of-#1352-upstream-release-2.9.0
Automated cherry pick of #1352: avoid duplicate network name
2019-06-24 12:33:49 +08:00
ioito
6f2dd84fba avoid duplicate network name 2019-06-24 11:25:01 +08:00
Zexi Li
b6e2223709 Merge pull request #1343 from Zexi/automated-cherry-pick-of-#1341-upstream-release-2.9.0
Automated cherry pick of #1341: scheduler: fix prefer avoid score
2019-06-21 14:06:17 +08:00
Zexi
5e56dc9d9e scheduler: fix prefer avoid score 2019-06-21 13:58:01 +08:00
yunion-ci-robot
9a71c2583d Merge pull request #1319 from wanyaoqi/automated-cherry-pick-of-#1316-upstream-release-2.9.0
Automated cherry pick of #1316: fix storage attach host sync status
2019-06-19 20:17:52 +08:00
wanyaoqi
3b52ac1cd8 fix storage attach host sync status 2019-06-19 20:02:29 +08:00
yunion-ci-robot
cfd62c200e Merge pull request #1307 from ioito/automated-cherry-pick-of-#1305-upstream-release-2.9.0
Automated cherry pick of #1305: dissocate and release eip optimized\
2019-06-19 18:06:51 +08:00
yunion-ci-robot
a2424e8d7d Merge pull request #1312 from ioito/automated-cherry-pick-of-#1273-upstream-release-2.9.0
Automated cherry pick of #1273: add azure region geographicinfo
2019-06-19 18:03:49 +08:00
yunion-ci-robot
cf660f6125 Merge pull request #1267 from ioito/automated-cherry-pick-of-#1265-upstream-release-2.9.0
Automated cherry pick of #1265: avoid openstack zone externalid equals
2019-06-19 17:45:52 +08:00
ioito
f98f50c539 add azure region geographicinfo 2019-06-19 17:41:53 +08:00
ioito
fc9f566d19 dissocate and release eip optimized\ 2019-06-19 16:29:38 +08:00
yunion-ci-robot
1068533dde Merge pull request #1281 from wanyaoqi/automated-cherry-pick-of-#1278-upstream-release-2.9.0
Automated cherry pick of #1278: filter storage not attached
2019-06-18 17:22:54 +08:00
wanyaoqi
e2e896adff filter storage not attached 2019-06-18 16:58:07 +08:00
yunion-ci-robot
477fea92bd Merge pull request #1252 from ioito/automated-cherry-pick-of-#1240-upstream-release-2.9.0
Automated cherry pick of #1240: choice valid storage for storagecache
2019-06-18 11:07:52 +08:00
ioito
a0a9e5f732 avoid openstack zone externalid equals 2019-06-17 21:01:28 +08:00
yunion-ci-robot
4a6396037e Merge pull request #1259 from wanyaoqi/automated-cherry-pick-of-#1256-upstream-release-2.9.0
Automated cherry pick of #1256: fix guest sync status interval
2019-06-17 15:51:53 +08:00
wanyaoqi
d11bf5439e fix guest sync status interval 2019-06-17 15:41:07 +08:00
ioito
b9229fadaf choice valid storage for storagecache 2019-06-17 10:16:25 +08:00
yunion-ci-robot
e7cbb129e3 Merge pull request #1214 from ioito/automated-cherry-pick-of-#1196-upstream-release-2.9.0
Automated cherry pick of #1196: fix balance permission error
2019-06-15 21:39:52 +08:00
ioito
de43a5d4de fix balance permission error 2019-06-15 13:49:20 +08:00
yunion-ci-robot
790fe00d39 Merge pull request #1208 from yousong/automated-cherry-pick-of-#1201-release-2.9.0
Automated cherry pick of #1201: cloudcommon: 移除非必要日志
2019-06-15 10:16:53 +08:00
Yousong Zhou
ad200c6134 cloudcommon: 移除非必要日志 2019-06-14 13:38:22 +00:00
yunion-ci-robot
3bcb2b1c47 Merge pull request #1170 from yousong/automated-cherry-pick-of-#1168-release-2.9.0
Automated cherry pick of #1168: webconsole: 改正文件权限
2019-06-13 14:23:54 +08:00
Yousong Zhou
5cff282694 webconsole: 改正文件权限
- 密钥不需要执行权限
 - 先改权限再写内容
2019-06-12 10:27:46 +00:00
yunion-ci-robot
08e0240184 Merge pull request #1166 from ioito/automated-cherry-pick-of-#1164-upstream-release-2.9.0
Automated cherry pick of #1164: 添加vpc操作日志
2019-06-12 18:01:51 +08:00
ioito
e796c6fd19 添加vpc操作日志 2019-06-12 16:59:43 +08:00
yunion-ci-robot
125e98613e Merge pull request #1155 from ioito/automated-cherry-pick-of-#1120-upstream-release-2.9.0
Automated cherry pick of #1120: network创建或删除后刷新调度缓存
2019-06-12 15:25:52 +08:00
yunion-ci-robot
a9200266a0 Merge pull request #1160 from wanyaoqi/automated-cherry-pick-of-#1158-upstream-release-2.9.0
Automated cherry pick of #1158: fix attach able storage
2019-06-12 14:43:53 +08:00
wanyaoqi
2ab4494aae fix attach able storage 2019-06-12 13:55:17 +08:00
ioito
1edabb5bee network创建或删除后刷新调度缓存 2019-06-12 11:41:37 +08:00
yunion-ci-robot
fd32813190 Merge pull request #1118 from ioito/automated-cherry-pick-of-#1116-upstream-release-2.9.0
Automated cherry pick of #1116: fix qcloud disk create name error
2019-06-12 09:04:52 +08:00
yunion-ci-robot
a16b357a5e Merge pull request #1140 from yousong/automated-cherry-pick-of-#1130-release-2.9.0
Automated cherry pick of #1130: networks: merge与split时将lbnetwork考虑进去
2019-06-11 23:05:51 +08:00
yunion-ci-robot
0c630655b0 Merge pull request #1137 from wanyaoqi/automated-cherry-pick-of-#1135-upstream-release-2.9.0
Automated cherry pick of #1135: fix disk delete task base
2019-06-11 20:32:54 +08:00
Yousong Zhou
e081b3cf97 networks: merge与split时将lbnetwork考虑进去
- 共用代码,并放到独立的文件中
 - 尽力更新,中途出错不中断,最后一起报出
2019-06-11 06:11:10 +00:00
wanyaoqi
fa0462b200 fix disk delete task base 2019-06-11 11:10:07 +08:00
yunion-ci-robot
1a7f933891 Merge pull request #1062 from Zexi/automated-cherry-pick-of-#1054-upstream-release-2.9.0
Automated cherry pick of #1054: fix: baremetal raid logical volume and block device map
2019-06-10 19:06:52 +08:00
Zexi
0892e8164d fix: baremetal find incorrect root disk 2019-06-10 18:01:26 +08:00
Zexi Li
a782c95968 Merge pull request #1124 from Zexi/automated-cherry-pick-of-#1122-upstream-release-2.9.0
Automated cherry pick of #1122: scheduler: recover panic when stop timer
2019-06-10 17:17:53 +08:00
Zexi
9eb6c11ace scheduler: recover panic when stop timer 2019-06-10 17:17:28 +08:00
ioito
1db84a7d92 fix qcloud disk create name error 2019-06-10 16:04:53 +08:00
yunion-ci-robot
5132c495cf Merge pull request #1109 from wanyaoqi/automated-cherry-pick-of-#1099-upstream-release-2.9.0
Automated cherry pick of #1099: fix reserved memory
2019-06-09 23:01:51 +08:00
wanyaoqi
7fa300e89a fix disk delete 2019-06-09 22:58:38 +08:00
wanyaoqi
9b64b9e4e4 fix reserved memory 2019-06-09 22:58:38 +08:00
yunion-ci-robot
74e8069559 Merge pull request #1105 from Zexi/automated-cherry-pick-of-#1104-upstream-release-2.9.0
Automated cherry pick of #1104: fix: disk input erase storage_id by backend
2019-06-09 11:18:51 +08:00
Zexi
71c79e85a3 fix: disk input erase storage_id by backend 2019-06-09 11:01:32 +08:00
yunion-ci-robot
ba66255113 Merge pull request #1102 from wanyaoqi/automated-cherry-pick-of-#1100-upstream-release-2.9.0
Automated cherry pick of #1100: gpfs
2019-06-09 00:59:54 +08:00
yunion-ci-robot
370437f31a Merge pull request #1094 from ioito/automated-cherry-pick-of-#1092-upstream-release-2.9.0
Automated cherry pick of #1092: 修复参数赋值问题
2019-06-06 23:25:51 +08:00
wanyaoqi
ab4d92fe62 gpfs 2019-06-06 23:23:23 +08:00
ioito
1d526124fa 修复参数赋值问题 2019-06-06 18:14:01 +08:00
yunion-ci-robot
086fa0d5b9 Merge pull request #1069 from Zexi/automated-cherry-pick-of-#1068-upstream-release-2.9.0
Automated cherry pick of #1068: fix: baremetal MegaRaid mul adapter parse error
2019-06-05 10:35:50 +08:00
Zexi
1e1d47508b fix: baremetal MegaRaid mul adapter parse error 2019-06-05 10:34:44 +08:00
yunion-ci-robot
231a98f2c0 Merge pull request #1066 from yousong/automated-cherry-pick-of-#1063-upstream-release-2.9.0
Automated cherry pick of #1063: cloudproviders: 调整lb资源清理顺序
2019-06-05 10:02:50 +08:00
Yousong Zhou
5d1845818a cloudproviders: 调整lb资源清理顺序
lbbg可能被lblis引用,应先清理lblis,再清理lbbg
2019-06-04 17:06:40 +00:00
yunion-ci-robot
cbe5d7d3f5 Merge pull request #1029 from ioito/automated-cherry-pick-of-#1024-upstream-release-2.9.0
Automated cherry pick of #1024: 避免未使用最优storage
2019-06-03 18:21:58 +08:00
yunion-ci-robot
3c37f6fe69 Merge pull request #1040 from wanyaoqi/automated-cherry-pick-of-#1038-upstream-release-2.9.0
Automated cherry pick of #1038: fix imported bm server start
2019-06-03 18:08:57 +08:00
wanyaoqi
7f0184060c fix imported bm server start 2019-06-03 15:27:42 +08:00
ioito
55aef9ba93 避免未使用最优storage 2019-06-03 10:07:13 +08:00
yunion-ci-robot
f491a57c0a Merge pull request #985 from swordqiu/automated-cherry-pick-of-#983-upstream-release-2.9.0
Automated cherry pick of #983: fix: esxi vm may fail on start or delete in batch
2019-05-31 13:52:19 +08:00
yunion-ci-robot
994a1aaa16 Merge pull request #1010 from yunion-ci-robot/cherry-pick-1009-to-release/2.9.0
[release/2.9.0] fix on guest migrate fail
2019-05-31 13:18:20 +08:00
wanyaoqi
da8af7285f fix on guest migrate fail 2019-05-31 05:15:43 +00:00
yunion-ci-robot
e874c36a0d Merge pull request #997 from yunion-ci-robot/cherry-pick-968-to-release/2.9.0
[release/2.9.0] 避免oUserData为nil时野指针访问
2019-05-30 17:49:22 +08:00
ioito
3e175495be 避免oUserData为nil时野指针访问 2019-05-30 09:37:28 +00:00
yunion-ci-robot
dda22b86ef Merge pull request #995 from yunion-ci-robot/cherry-pick-993-to-release/2.9.0
[release/2.9.0] fix guest display metadata
2019-05-30 16:56:25 +08:00
wanyaoqi
a1d49c164c fix guest display metadata 2019-05-30 08:48:52 +00:00
yunion-ci-robot
fb157228b2 Merge pull request #988 from yunion-ci-robot/cherry-pick-955-to-release/2.9.0
[release/2.9.0] 避免webconsole频繁连接server,导致IP被封禁
2019-05-30 15:16:18 +08:00
ioito
73b4a94bed 避免频繁连接server 2019-05-30 07:04:07 +00:00
Qiu Jian
677dcfe828 fix: esxi vm may fail on start or delete in batch 2019-05-30 14:43:32 +08:00
yunion-ci-robot
7b3d4ecd39 Merge pull request #981 from Zexi/automated-cherry-pick-of-#978-upstream-release-2.9.0
Automated cherry pick of #978: scheduler: add pending usage process
2019-05-29 20:40:20 +08:00
Zexi
d21c90ebed scheduler: add pending usage process 2019-05-29 19:58:37 +08:00
yunion-ci-robot
d66baab597 Merge pull request #973 from yunion-ci-robot/cherry-pick-971-to-release/2.9.0
[release/2.9.0] scheduler: fix nets result not select
2019-05-29 16:24:18 +08:00
Zexi
10cc2d2871 scheduler: fix nets result not select 2019-05-29 08:19:45 +00:00
yunion-ci-robot
e54f98e322 Merge pull request #965 from yunion-ci-robot/cherry-pick-956-to-release/2.9.0
[release/2.9.0] lb: 支持直接指定ip作为后端
2019-05-29 11:44:20 +08:00
Yousong Zhou
a01ae4f987 mcclient: options: use --loadbalancer for consistency
Fixes 2df78f
2019-05-29 01:51:47 +00:00
Yousong Zhou
4218f260c1 loadbalancerbackends: 支持直接指定IP地址 2019-05-29 01:51:47 +00:00
yunion-ci-robot
f815ff26b7 Merge pull request #963 from Zexi/automated-cherry-pick-of-#961-upstream-release-2.9.0
Automated cherry pick of #961: fix: schedule fatal error concurrent map writes
2019-05-29 09:51:19 +08:00
Zexi
a4ffa1dc20 fix: schedule fatal error concurrent map writes 2019-05-29 09:46:43 +08:00
yunion-ci-robot
07686c5d54 Merge pull request #953 from ioito/automated-cherry-pick-of-#943-upstream-release-2.9.0
Automated cherry pick of #943: 避免转换成shell格式后导致合并失败
2019-05-28 22:03:24 +08:00
yunion-ci-robot
23af7e93fc Merge pull request #959 from Zexi/hotfix/schedule-panic
backport fix: scheduler hypervisor panic
2019-05-28 20:45:18 +08:00
Zexi
2686324722 fix: scheduler hypervisor panic 2019-05-28 20:34:35 +08:00
ioito
f5fb8e7a64 避免转换成shell格式后导致合并失败 2019-05-28 17:01:01 +08:00
yunion-ci-robot
1ef132b7da Merge pull request #950 from wanyaoqi/automated-cherry-pick-of-#947-upstream-release-2.9.0
Automated cherry pick of #947: support add pid file
2019-05-28 16:13:19 +08:00
wanyaoqi
474a6960c5 support add pid file 2019-05-28 16:00:49 +08:00
yunion-ci-robot
794d1b9547 Merge pull request #941 from yunion-ci-robot/cherry-pick-933-to-release/2.9.0
[release/2.9.0] routetables: 改正同步
2019-05-28 13:41:19 +08:00
yunion-ci-robot
7227eae4b8 Merge pull request #936 from yunion-ci-robot/cherry-pick-932-to-release/2.9.0
[release/2.9.0] 补充缺失的task stage
2019-05-28 13:31:19 +08:00
yunion-ci-robot
48abeb350b Merge pull request #945 from wanyaoqi/automated-cherry-pick-of-#934-upstream-release-2.9.0
Automated cherry pick of #934: bugfix:
2019-05-28 12:13:18 +08:00
wanyaoqi
7b48d52346 bugfix:
- fix import from libvirt
- fix server deploy
- fix guest migrate
- golang host bugfix
2019-05-28 12:05:20 +08:00
Yousong Zhou
2f938a9134 routetables: default to name rtbl-<vpc.name> 2019-05-27 12:55:45 +00:00
Yousong Zhou
f8a99dfc09 routetables: sync: add vpc-awareness 2019-05-27 12:55:45 +00:00
ioito
50b1ec9cb6 补充缺失的task stage 2019-05-27 12:52:02 +00:00
yunion-ci-robot
d90c599881 Merge pull request #930 from ioito/automated-cherry-pick-of-#899-upstream-release-2.9.0
Automated cherry pick of #899: 删除账号时删除空的zone及region
2019-05-25 20:39:18 +08:00
yunion-ci-robot
ee8528d91f Merge pull request #925 from ioito/automated-cherry-pick-of-#883-upstream-release-2.9.0
Automated cherry pick of #883: 避免同步出现重复eip记录
2019-05-25 20:37:19 +08:00
ioito
8110dcbad4 删除账号时删除空的zone及region 2019-05-25 20:25:35 +08:00
ioito
ebf641a4b0 避免同步出现重复eip记录 2019-05-25 17:55:44 +08:00
yunion-ci-robot
7eed67e9f0 Merge pull request #923 from yunion-ci-robot/cherry-pick-921-to-release/2.9.0
[release/2.9.0] 校验aliyun eip带宽范围
2019-05-25 17:51:18 +08:00
ioito
1e516eb076 校验aliyun eip带宽范围 2019-05-25 09:39:28 +00:00
yunion-ci-robot
25e99cc231 Merge pull request #917 from ioito/automated-cherry-pick-of-#894-upstream-release-2.9.0
Automated cherry pick of #894: 避免keystone region中使用-导致region被截取
2019-05-25 11:02:18 +08:00
ioito
14787f2bf2 避免keystone region中使用-导致region被截取 2019-05-25 09:56:09 +08:00
yunion-ci-robot
5ad60ae964 Merge pull request #913 from wanyaoqi/automated-cherry-pick-of-#900-upstream-release-2.9.0
Automated cherry pick of #900: misc fix:
2019-05-24 14:44:19 +08:00
wanyaoqi
230f30f413 misc fix:
- fix undeploy backup guest
- fix host service cron job
- task add recover
2019-05-24 13:31:17 +08:00
yunion-ci-robot
944fc4427e Merge pull request #912 from yunion-ci-robot/cherry-pick-886-to-release/2.9.0
[release/2.9.0] huawei & ucloud bugfix
2019-05-24 12:19:17 +08:00
TangBin
962696e36e huawei & ucloud bugfix 2019-05-24 04:15:35 +00:00
yunion-ci-robot
bd72bf3f61 Merge pull request #905 from yunion-ci-robot/cherry-pick-896-to-release/2.9.0
[release/2.9.0] 修复多账号导致openstack region同步异常
2019-05-24 10:15:18 +08:00
ioito
de1dafb597 未设置正确的region prefix 2019-05-24 01:48:31 +00:00
yunion-ci-robot
c6f3946709 Merge pull request #903 from yunion-ci-robot/cherry-pick-890-to-release/2.9.0
[release/2.9.0] guests: 变更IP地址时尽量保留原网卡设定
2019-05-24 09:48:18 +08:00
Yousong Zhou
35f0d96ea3 guests: change-ipaddr: 尽量保留原网卡配置
网卡序号,带宽限定等

Reported-by: Wenlong Wang
2019-05-24 01:42:25 +00:00
yunion-ci-robot
c933fef8f6 Merge pull request #902 from yunion-ci-robot/cherry-pick-895-to-release/2.9.0
[release/2.9.0] baremetal: fix build HPSARaid and enable serial console errors
2019-05-24 09:40:17 +08:00
Zexi
12e5d02361 baremetal: fix build HPSARaid and enable serial console errors 2019-05-24 01:39:27 +00:00
yunion-ci-robot
2adc97be4c Merge pull request #884 from yousong/automated-cherry-pick-of-#880-release-2.9.0
Automated cherry pick of #880: mcclient: RouteOptions: 缩短命令行参数长度
2019-05-23 16:21:18 +08:00
yunion-ci-robot
2cf0e60db5 Merge pull request #891 from wanyaoqi/automated-cherry-pick-of-#888-upstream-release-2.9.0
Automated cherry pick of #888: - set disk storage_id not required - can't do syncstatus on guest has active tasks in last one hour - fix guestdisk index set wrong number on guest attach disk
2019-05-23 10:53:17 +08:00
wanyaoqi
158ccac14a - set disk storage_id not required - can't do syncstatus on guest has active tasks in last one hour - fix guestdisk index set wrong number on guest attach disk 2019-05-23 10:46:54 +08:00
Yousong Zhou
8ed7cbf036 climc: 在打印路由条目时显示下一跳资源id 2019-05-22 04:00:09 +00:00
Yousong Zhou
1dbeedc736 routetables: 厘清指针使用 2019-05-22 04:00:09 +00:00
Yousong Zhou
42b268130d mcclient: 使--vpc成为必选参数 2019-05-22 04:00:09 +00:00
Yousong Zhou
52666dc4af mcclient: RouteOptions: 缩短命令行参数长度 2019-05-22 04:00:09 +00:00
yunion-ci-robot
e8b1fae2da Merge pull request #876 from ioito/automated-cherry-pick-of-#875-upstream-release-2.9.0
Automated cherry pick of #875: openstack认证添加domain_name参数
2019-05-21 21:33:16 +08:00
ioito
9862bf4522 openstack认证添加domain_name参数 2019-05-21 17:30:07 +08:00
yunion-ci-robot
667a1316a1 Merge pull request #873 from ioito/automated-cherry-pick-of-#860-upstream-release-2.9.0
Automated cherry pick of #860: 使用driver注入密码,复用代码
2019-05-21 14:03:21 +08:00
ioito
27e03a104d 避免climc使用公有云镜像时未设置prefix region导致虚拟机创建失败 2019-05-21 13:32:20 +08:00
ioito
6fddbfead1 使用driver注入密码,复用代码 2019-05-21 13:32:20 +08:00
yunion-ci-robot
140828e20a Merge pull request #871 from tb365/automated-cherry-pick-of-#841-upstream-release-2.9.0
Automated cherry pick of #841: ucloud bugfix
2019-05-21 11:36:16 +08:00
TangBin
bcb6fb574d ucloud bugfix 2019-05-21 11:27:50 +08:00
yunion-ci-robot
5d7be005ae Merge pull request #867 from ioito/automated-cherry-pick-of-#866-upstream-release-2.9.0
Automated cherry pick of #866: fix openstack region sync
2019-05-20 22:40:19 +08:00
yunion-ci-robot
041742f83f Merge pull request #865 from yunion-ci-robot/cherry-pick-861-to-release/2.9.0
[release/2.9.0] fix: host undo convert not delete isolated_devices
2019-05-20 22:21:21 +08:00
ioito
fd4f6368d8 fix openstack region sync 2019-05-20 22:18:15 +08:00
yunion-ci-robot
ee8fe1827b Merge pull request #863 from ioito/automated-cherry-pick-of-#859-upstream-release-2.9.0
Automated cherry pick of #859: 不同类型的tag使用对应的参数进行过滤
2019-05-20 21:29:20 +08:00
Zexi
b5d79ff132 fix: host undo convert not delete isolated_devices 2019-05-20 13:22:49 +00:00
ioito
e10373f55d 不同类型的tag使用对应的参数进行过滤 2019-05-20 21:19:10 +08:00
yunion-ci-robot
5fec676627 Merge pull request #856 from ioito/automated-cherry-pick-of-#855-upstream-release-2.9.0
Automated cherry pick of #855: 修复调用错误方法
2019-05-20 14:06:17 +08:00
ioito
1857cfd86d 修复调用错误方法 2019-05-20 13:47:38 +08:00
yunion-ci-robot
af2740e2b6 Merge pull request #853 from ioito/automated-cherry-pick-of-#842-upstream-release-2.9.0
Automated cherry pick of #842: 删除虚拟机同时删除lb相关记录
2019-05-18 20:20:18 +08:00
yunion-ci-robot
f722a45d36 Merge pull request #852 from ioito/automated-cherry-pick-of-#840-upstream-release-2.9.0
Automated cherry pick of #840: 保持公有云镜像名称和本地镜像名称相同
2019-05-18 20:18:15 +08:00
ioito
389adf7522 删除虚拟机同时删除lb相关记录 2019-05-18 20:15:14 +08:00
ioito
9f388206b1 保持公有云镜像名称和本地镜像名称相同 2019-05-18 20:13:22 +08:00
yunion-ci-robot
19937c96c5 Merge pull request #851 from Zexi/automated-cherry-pick-of-#850-upstream-release-2.9.0
Automated cherry pick of #850: fix: SSHPartition test symbolic file exists fail
2019-05-18 19:45:17 +08:00
Zexi
122e18c8f5 fix: SSHPartition test symbolic file exists fail 2019-05-18 19:42:12 +08:00
yunion-ci-robot
8c0b29e883 Merge pull request #849 from Zexi/automated-cherry-pick-of-#848-upstream-release-2.9.0
Automated cherry pick of #848: fix: baremetal enable serial not working
2019-05-17 16:05:17 +08:00
Zexi
360dfd3d29 fix: baremetal enable serial not working 2019-05-17 15:07:57 +08:00
yunion-ci-robot
d1b1df95eb Merge pull request #847 from wanyaoqi/automated-cherry-pick-of-#846-upstream-release-2.9.0
Automated cherry pick of #846: fix guest on start failed no call task failed
2019-05-17 14:36:18 +08:00
wanyaoqi
8f6df4bf49 fix live migrate 2019-05-17 14:31:32 +08:00
wanyaoqi
9f3ee0c55e fix guest on start failed no call task failed 2019-05-17 14:31:32 +08:00
yunion-ci-robot
f649fa14cd Merge pull request #844 from Zexi/automated-cherry-pick-of-#843-upstream-release-2.9.0
Automated cherry pick of #843: use scheduler apply sched policies
2019-05-17 10:20:17 +08:00
Zexi
ec744fd900 use scheduler apply sched policies 2019-05-16 20:59:01 +08:00
yunion-ci-robot
13d5fea826 Merge pull request #839 from wanyaoqi/automated-cherry-pick-of-#836-upstream-release-2.9.0
Automated cherry pick of #836: fix set migrate capability, fix resize fs catch error
2019-05-16 17:53:28 +08:00
wanyaoqi
d6126c537e fix set migrate capability, fix resize fs catch error 2019-05-16 17:14:30 +08:00
yunion-ci-robot
fa5f16dbbd Merge pull request #837 from ioito/automated-cherry-pick-of-#810-upstream-release-2.9.0
Automated cherry pick of #810: 限制添加同一个vpc底下的虚拟机
2019-05-16 16:56:37 +08:00
ioito
9053d1a5b1 避免关不掉访问控制 2019-05-16 16:46:33 +08:00
ioito
5a25e90cfd 显示acl名称 2019-05-16 16:46:33 +08:00
ioito
92998237f5 限制添加同一个vpc底下的虚拟机 2019-05-16 16:46:33 +08:00
yunion-ci-robot
807c65453a Merge pull request #835 from yunion-ci-robot/cherry-pick-823-to-release/2.9.0
[release/2.9.0] The region service adds restful-list to display zone and zone_id information.
2019-05-16 14:49:35 +08:00
zhongcan
d382af04d6 The region service adds restful-list to display zone and zone_id information. 2019-05-16 06:47:18 +00:00
yunion-ci-robot
3df4f13203 Merge pull request #834 from Zexi/automated-cherry-pick-of-#833-upstream-release-2.9.0
Automated cherry pick of #833: baremetal: support http download kernel and initramfs for pxe boot
2019-05-16 14:44:35 +08:00
Zexi
8b24b592de baremetal: support http download kernel and initramfs for pxe boot 2019-05-16 13:44:03 +08:00
yunion-ci-robot
053f9b1bc9 Merge pull request #831 from ioito/automated-cherry-pick-of-#830-upstream-release-2.9.0
Automated cherry pick of #830: 修复删除账号错误
2019-05-16 12:34:35 +08:00
ioito
d9f618438b 修复删除账号错误 2019-05-16 12:23:14 +08:00
yunion-ci-robot
a45b1c5726 Merge pull request #828 from yunion-ci-robot/cherry-pick-827-to-release/2.9.0
[release/2.9.0] bugfix: fix host setup network
2019-05-16 00:31:35 +08:00
wanyaoqi
2324309124 fix host setup network 2019-05-15 16:29:47 +00:00
yunion-ci-robot
23ec792ceb Merge pull request #825 from yunion-ci-robot/cherry-pick-822-to-release/2.9.0
[release/2.9.0] OpenStack: 增加同步数据准确性
2019-05-15 22:49:37 +08:00
ioito
6073eae13c 增加同步数据准确性 2019-05-15 14:46:23 +00:00
yunion-ci-robot
a743e123bd Merge pull request #820 from yunion-ci-robot/cherry-pick-811-to-release/2.9.0
[release/2.9.0] bugfix: host cpuset bugfix
2019-05-15 17:08:37 +08:00
wanyaoqi
d96d0568d4 guest fix set oom_adj 2019-05-15 08:55:51 +00:00
wanyaoqi
f54e0a54d3 host cpuset bugfix 2019-05-15 08:55:51 +00:00
yunion-ci-robot
571ebebdbe Merge pull request #819 from yunion-ci-robot/cherry-pick-812-to-release/2.9.0
[release/2.9.0] 设置端口和权重后同步到公有云上
2019-05-15 16:53:35 +08:00
ioito
72e89d2a71 设置端口和权重后同步到公有云上 2019-05-15 08:51:46 +00:00
yunion-ci-robot
fa1edb4349 Merge pull request #817 from yunion-ci-robot/cherry-pick-809-to-release/2.9.0
[release/2.9.0] bugfix: disable clean iptables && fix mac equal
2019-05-15 16:49:36 +08:00
wanyaoqi
2ea7757b1e disable clean iptables && fix mac equal 2019-05-15 08:36:55 +00:00
yunion-ci-robot
82c07ea01f Merge pull request #815 from yunion-ci-robot/cherry-pick-813-to-release/2.9.0
[release/2.9.0] 避免使用错误方法损坏id
2019-05-15 14:59:34 +08:00
ioito
7f2f6dc4fd 避免使用错误方法损坏id 2019-05-15 06:58:38 +00:00
yunion-ci-robot
455c536b6c Merge pull request #807 from wanyaoqi/automated-cherry-pick-of-#755-upstream-release-2.9.0
Automated cherry pick of #755: - host dhcp srever start after guest manager init - fix cpuset out of range
2019-05-14 11:02:34 +08:00
wanyaoqi
f7008d86c0 - host dhcp srever start after guest manager init - fix cpuset out of range 2019-05-14 10:59:08 +08:00
yunion-ci-robot
cfa8c38b68 Merge pull request #805 from yunion-ci-robot/cherry-pick-802-to-release/2.9.0
[release/2.9.0] feature: disable cron jobs on slave node
2019-05-13 21:22:34 +08:00
wanyaoqi
5370edcfcd disable cron jobs on slave node 2019-05-13 13:12:23 +00:00
yunion-ci-robot
ad40b066d1 Merge pull request #800 from yunion-ci-robot/cherry-pick-784-to-release/2.9.0
[release/2.9.0] 避免创建时使用不同公有云的镜像
2019-05-13 19:20:34 +08:00
yunion-ci-robot
17f2bed403 Merge pull request #799 from yunion-ci-robot/cherry-pick-797-to-release/2.9.0
[release/2.9.0] fix: scheduler not init app db
2019-05-13 19:19:36 +08:00
ioito
99985cbe82 避免创建时使用不同公有云的镜像 2019-05-13 11:17:47 +00:00
Zexi
807bfb31c3 fix: scheduler not init app db 2019-05-13 11:15:44 +00:00
yunion-ci-robot
b3e07e87ad Merge pull request #794 from yunion-ci-robot/cherry-pick-791-to-release/2.9.0
[release/2.9.0] 避免任务完成后依然返回timeout错误
2019-05-13 17:08:34 +08:00
yunion-ci-robot
2e2afedf6b Merge pull request #792 from yunion-ci-robot/cherry-pick-790-to-release/2.9.0
[release/2.9.0] bugfix : fix start script no pid file
2019-05-13 16:59:34 +08:00
ioito
565991fc36 避免任务完成后依然返回timeout错误 2019-05-13 08:52:50 +00:00
wanyaoqi
c353e618e6 fix no pid file 2019-05-13 08:51:45 +00:00
yunion-ci-robot
96f438d3ae Merge pull request #787 from yunion-ci-robot/cherry-pick-786-to-release/2.9.0
[release/2.9.0] bugfix: fix guest delele backup log event
2019-05-13 11:27:35 +08:00
yunion-ci-robot
61daae575e Merge pull request #789 from yunion-ci-robot/cherry-pick-785-to-release/2.9.0
[release/2.9.0] fix: add host convert same disk spec check
2019-05-13 11:22:34 +08:00
Zexi
a4655a272f fix: add host convert same disk spec check 2019-05-13 03:21:46 +00:00
wanyaoqi
8ae4dc70b7 fix guest delele backup log event 2019-05-13 03:17:52 +00:00
yunion-ci-robot
37fa97efd7 Merge pull request #783 from yunion-ci-robot/cherry-pick-772-to-release/2.9.0
[release/2.9.0] add ucloud account create climc
2019-05-11 17:57:33 +08:00
yunion-ci-robot
f11c310125 Merge pull request #782 from yunion-ci-robot/cherry-pick-778-to-release/2.9.0
[release/2.9.0] 允许普通用户set manager_id
2019-05-11 17:42:34 +08:00
TangBin
2f1319b4fe ucloud subaccount name fix 2019-05-11 09:42:05 +00:00
TangBin
5536f2bd96 ucloud eip default charge type Dynamic 2019-05-11 09:42:05 +00:00
TangBin
fd09a65c55 add ucloud account create climc & get disks bugfix 2019-05-11 09:42:05 +00:00
yunion-ci-robot
ea0707fa60 Merge pull request #780 from yunion-ci-robot/cherry-pick-769-to-release/2.9.0
[release/2.9.0] 负载均衡日志补全
2019-05-11 17:30:33 +08:00
ioito
95c25a0880 允许普通用户set manager_id 2019-05-11 09:27:02 +00:00
ioito
f7834caa98 负载均衡日志补全 2019-05-11 09:24:08 +00:00
yunion-ci-robot
48678ca9f2 Merge pull request #776 from yunion-ci-robot/cherry-pick-759-to-release/2.9.0
[release/2.9.0] Aliyun: 避免cache image失败
2019-05-11 17:12:35 +08:00
ioito
e64971b697 避免cache image失败 2019-05-11 09:01:54 +00:00
yunion-ci-robot
02b466c685 Merge pull request #774 from yunion-ci-robot/cherry-pick-770-to-release/2.9.0
[release/2.9.0] bugfix:  fix host deploy windows password, user can get backup host id
2019-05-10 21:12:34 +08:00
wanyaoqi
44b76bfb8a qemu prevent oom 2019-05-10 12:54:52 +00:00
wanyaoqi
799e976f55 fix host deploy windows password 2019-05-10 12:54:52 +00:00
wanyaoqi
09abdd39d4 user can get backup host id 2019-05-10 12:54:52 +00:00
yunion-ci-robot
b707a2365b Merge pull request #768 from yunion-ci-robot/cherry-pick-767-to-release/2.9.0
[release/2.9.0] 移除多余的方法
2019-05-09 22:01:34 +08:00
ioito
91f53b1d50 移除多余的方法 2019-05-09 11:50:45 +00:00
yunion-ci-robot
12e2018326 Merge pull request #765 from yunion-ci-robot/cherry-pick-747-to-release/2.9.0
[release/2.9.0] sku provider filter by zone
2019-05-09 18:20:34 +08:00
yunion-ci-robot
c2f6c8813d Merge pull request #763 from yunion-ci-robot/cherry-pick-762-to-release/2.9.0
[release/2.9.0] 避免显示脏的image信息
2019-05-09 18:19:34 +08:00
TangBin
3543d0ce00 sku providerFilter add more comment 2019-05-09 09:53:11 +00:00
TangBin
30c6091813 sku provider filter by region 2019-05-09 09:53:11 +00:00
TangBin
c177c7d5b5 sku provider filter by zone 2019-05-09 09:53:11 +00:00
ioito
d33bb4aa97 避免显示脏的image信息 2019-05-09 09:51:45 +00:00
yunion-ci-robot
b0350b9e2c Merge pull request #760 from wanyaoqi/automated-cherry-pick-of-#758-upstream-release-2.9.0
Automated cherry pick of #758: fix go vet report bugs
2019-05-09 15:11:35 +08:00
wanyaoqi
011e808286 Readme add go reporter 2019-05-09 15:06:15 +08:00
wanyaoqi
349d98d6b1 fix go vet report bugs 2019-05-09 15:06:15 +08:00
yunion-ci-robot
3abce7094a Merge pull request #756 from yunion-ci-robot/cherry-pick-754-to-release/2.9.0
[release/2.9.0] bugfix :fix get storage by access path
2019-05-08 18:25:34 +08:00
wanyaoqi
e4e933577d fix get storage by access path 2019-05-08 10:23:05 +00:00
yunion-ci-robot
c779d71f06 Merge pull request #752 from yunion-ci-robot/cherry-pick-749-to-release/2.9.0
[release/2.9.0] fix: admaster bug, disk-purge nil pointer error
2019-05-08 13:29:34 +08:00
Qiu Jian
f455c7dda9 fix: admaster bug, disk-purge nil pointer error 2019-05-08 05:27:44 +00:00
yunion-ci-robot
f6e055220c Merge pull request #750 from yunion-ci-robot/cherry-pick-748-to-release/2.9.0
[release/2.9.0] bugfix: fix sync status on stoping
2019-05-08 13:15:33 +08:00
wanyaoqi
a9c02dcf4c fix sync status on stoping 2019-05-08 04:53:50 +00:00
yunion-ci-robot
891e23db39 Merge pull request #743 from yunion-ci-robot/cherry-pick-726-to-release/2.9.0
[release/2.9.0] set host is import && fix notify template
2019-05-07 13:08:15 +08:00
yunion-ci-robot
5cc2311c30 Merge pull request #741 from yunion-ci-robot/cherry-pick-725-to-release/2.9.0
[release/2.9.0] bugfix: fix host image service, disable https
2019-05-07 13:07:16 +08:00
yunion-ci-robot
7313d86969 Merge pull request #740 from yunion-ci-robot/cherry-pick-731-to-release/2.9.0
[release/2.9.0] remove gpu passthrough params addr
2019-05-07 13:06:14 +08:00
wanyaoqi
e828e7f5a4 set host is import && fix notify template 2019-05-07 04:32:26 +00:00
wanyaoqi
db8c960289 fix host image service, disable https 2019-05-07 04:31:33 +00:00
yunion-ci-robot
2941d21682 Merge pull request #738 from yunion-ci-robot/cherry-pick-736-to-release/2.9.0
[release/2.9.0] fix: resource set schedtags
2019-05-07 12:18:15 +08:00
wanyaoqi
56fe3d052d remove gpu passthrough params addr 2019-05-07 04:17:50 +00:00
Zexi
0f20051eab fix: resource set schedtags 2019-05-07 04:16:46 +00:00
yunion-ci-robot
55b7e96916 Merge pull request #735 from yunion-ci-robot/cherry-pick-730-to-release/2.9.0
[release/2.9.0] fix: FetchModelExtraCountProperties find empty method name
2019-05-07 12:10:17 +08:00
Qiu Jian
0b2fcd4d0d fix: FetchModelExtraCountProperties find empty method name 2019-05-07 03:57:25 +00:00
yunion-ci-robot
df9c8a2121 Merge pull request #734 from yunion-ci-robot/cherry-pick-732-to-release/2.9.0
[release/2.9.0] update host batch register
2019-05-07 11:32:15 +08:00
TangBin
0842c17549 update host batch register 2019-05-07 03:30:28 +00:00
yunion-ci-robot
d1d3f0a1ff Merge pull request #729 from yunion-ci-robot/cherry-pick-728-to-release/2.9.0
[release/2.9.0] fix: fail to create network in default vpc
2019-05-06 21:21:15 +08:00
Qiu Jian
c9f87f08c7 fix: fail to create network in default vpc 2019-05-06 13:15:33 +00:00
yunion-ci-robot
b22bdf23cb Merge pull request #722 from yunion-ci-robot/cherry-pick-719-to-release/2.9.0
[release/2.9.0] fix: create backup server panic when schedule
2019-05-05 21:14:14 +08:00
Zexi
5adb5797a8 fix: create backup server panic when schedule 2019-05-05 13:10:29 +00:00
yunion-ci-robot
185c098430 Merge pull request #720 from Zexi/automated-cherry-pick-of-#716-upstream-release-2.9.0
Automated cherry pick of #716: fix baremetal disk config auto extend not work and ipmi_info not record
2019-05-05 20:51:13 +08:00
Zexi
12f54ef044 fix baremetal disk config auto extend not work and ipmi_info not record 2019-05-05 20:10:47 +08:00
yunion-ci-robot
0a1d39619c Merge pull request #717 from yunion-ci-robot/cherry-pick-711-to-release/2.9.0
[release/2.9.0] bugfix:  fix delete backup status
2019-05-05 19:54:15 +08:00
wanyaoqi
f6c07a838d fix backup status 2019-05-05 11:06:26 +00:00
yunion-ci-robot
b261b81c98 Merge pull request #714 from yunion-ci-robot/cherry-pick-710-to-release/2.9.0
[release/2.9.0] 设置镜像hw_qemu_guest_agent属性
2019-05-05 16:52:15 +08:00
yunion-ci-robot
6d13364b30 Merge pull request #713 from yunion-ci-robot/cherry-pick-699-to-release/2.9.0
[release/2.9.0] bugfix: fix baremetal online prepare!
2019-05-05 16:51:15 +08:00
ioito
3af6ae567f 设置镜像hw_qemu_guest_agent属性 2019-05-05 08:36:26 +00:00
wanyaoqi
41673924d4 fix baremetal online prepare! 2019-05-05 04:36:05 +00:00
yunion-ci-robot
8ef8969392 Merge pull request #709 from tb365/automated-cherry-pick-of-#366-upstream-release-2.9.0
Automated cherry pick of #366: add ucloud operations
2019-05-05 11:56:13 +08:00
TangBin
ecddd5021f ucloud normalizeOsName bugfix 2019-05-05 11:47:18 +08:00
TangBin
03938baee9 fix comment 2019-05-05 11:47:17 +08:00
TangBin
581938e372 fix ucloudcli instance-create 2019-05-05 11:47:17 +08:00
TangBin
4792047cfb fix comment 2019-05-05 11:47:17 +08:00
TangBin
46d573401b add ucloud operations 2019-05-05 11:47:17 +08:00
yunion-ci-robot
242c6cde8c Merge pull request #707 from yunion-ci-robot/cherry-pick-456-to-release/2.9.0
[release/2.9.0] 添加阿里云lb监听参数校验
2019-05-05 11:27:13 +08:00
ioito
4a765bdda9 添加阿里云lb监听参数校验 2019-05-05 03:18:25 +00:00
yunion-ci-robot
9944417443 Merge pull request #706 from yunion-ci-robot/cherry-pick-690-to-release/2.9.0
[release/2.9.0] fix: 1. ignore yunioncloud temp VMs when syncing 2. start esxi VM on same host with lock
2019-05-02 12:05:14 +08:00
Qiu Jian
8ba76a67f2 fix: 1. ignore yunioncloud temp VMs when syncing 2. start esxi VM on same host with lock 2019-05-02 04:03:41 +00:00
yunion-ci-robot
19f3d6a6ac Merge pull request #703 from yunion-ci-robot/cherry-pick-700-to-release/2.9.0
[release/2.9.0] feature: golang host support linux bridge
2019-05-02 10:42:13 +08:00
wanyaoqi
237e861704 golang host support linux bridge 2019-05-02 02:35:32 +00:00
yunion-ci-robot
40dfc7cd91 Merge pull request #701 from yunion-ci-robot/cherry-pick-671-to-release/2.9.0
[release/2.9.0] 修复腾讯云本地和云上out方向规则为空语义不一致问题
2019-05-01 12:02:14 +08:00
ioito
795491d2b3 修复腾讯云本地和云上out方向规则为空语义不一致问题 2019-05-01 03:52:26 +00:00
yunion-ci-robot
8eeaa08841 Merge pull request #698 from yunion-ci-robot/cherry-pick-696-to-release/2.9.0
[release/2.9.0] fix: deploy_configs was removed when invoke SetCreateParams
2019-04-30 16:43:18 +08:00
Zexi
84190d147c fix: deploy_configs was removed when invoke SetCreateParams 2019-04-30 08:26:18 +00:00
yunion-ci-robot
3c5407051b Merge pull request #695 from yunion-ci-robot/cherry-pick-693-to-release/2.9.0
[release/2.9.0] fix: isolated_device dev_type field not set
2019-04-30 14:34:14 +08:00
Zexi
665fa8f325 fix: isolated_device dev_type field not set 2019-04-30 06:30:42 +00:00
yunion-ci-robot
84aadaa880 Merge pull request #692 from yunion-ci-robot/cherry-pick-689-to-release/2.9.0
[release/2.9.0] netio&diskio fix
2019-04-30 14:28:13 +08:00
TangBin
88a40f0609 rename addNetio variable name 2019-04-30 02:43:35 +00:00
TangBin
972c5b4793 netio&diskio fix 2019-04-30 02:43:35 +00:00
yunion-ci-robot
d7b7930f27 Merge pull request #682 from yunion-ci-robot/cherry-pick-679-to-release/2.9.0
[release/2.9.0] bugfix: host register add version record, fix getBmAgentUrl
2019-04-29 14:29:12 +08:00
yunion-ci-robot
ed89158113 Merge pull request #685 from yunion-ci-robot/cherry-pick-659-to-release/2.9.0
[release/2.9.0] fix: keep order of network interface for baremetal
2019-04-29 14:27:16 +08:00
Qiu Jian
c446585812 fix: keep order of network interface for baremetal 2019-04-29 06:24:46 +00:00
yunion-ci-robot
02ba19b7d4 Merge pull request #680 from yunion-ci-robot/cherry-pick-678-to-release/2.9.0
[release/2.9.0] fix: host convert params to ServerCreateInput
2019-04-29 14:21:13 +08:00
wanyaoqi
d83b885c2b host register add version record, fix getBmAgentUrl 2019-04-29 05:38:27 +00:00
Zexi
577d310abd fix: host convert params to ServerCreateInput 2019-04-29 05:36:29 +00:00
yunion-ci-robot
d821c37c3e Merge pull request #676 from yunion-ci-robot/cherry-pick-675-to-release/2.9.0
[release/2.9.0] scheduler forecast select_candidate not add count
2019-04-28 21:58:13 +08:00
Zexi
c7e601171c fix: scheduler forecast select_candidate not add count 2019-04-28 13:55:30 +00:00
yunion-ci-robot
e0c4e2c267 Merge pull request #673 from yunion-ci-robot/cherry-pick-672-to-release/2.9.0
[release/2.9.0] 统一使用const,避免city命名不一致
2019-04-28 17:03:12 +08:00
ioito
5758d04e2e 统一使用const,避免city命名不一致 2019-04-28 07:48:49 +00:00
yunion-ci-robot
28fa859061 Merge pull request #667 from yunion-ci-robot/cherry-pick-665-to-release/2.9.0
[release/2.9.0] 修复未返回templateId
2019-04-27 21:31:17 +08:00
ioito
64a5ee2b9f 修复未返回templateId 2019-04-27 13:24:57 +00:00
yunion-ci-robot
531c7b24db Merge pull request #661 from yunion-ci-robot/cherry-pick-660-to-release/2.9.0
[release/2.9.0] 避免nil指针访问
2019-04-27 17:23:13 +08:00
ioito
4e1dffcbfb 避免nil指针访问 2019-04-27 09:21:24 +00:00
yunion-ci-robot
5d0093603d Merge pull request #655 from yunion-ci-robot/cherry-pick-600-to-release/2.9.0
[release/2.9.0] OpenStack加入重装系统参数校验
2019-04-26 22:24:20 +08:00
yunion-ci-robot
8e85e9d6fd Merge pull request #653 from yunion-ci-robot/cherry-pick-646-to-release/2.9.0
[release/2.9.0] fix: do not directly manage ESXi host that is managed by vcenter
2019-04-26 21:43:12 +08:00
ioito
06c73d203b 加入重装系统参数校验 2019-04-26 13:42:25 +00:00
Qiu Jian
59e5c1afac fix: do not directly manage ESXi host that is managed by vcenter 2019-04-26 13:19:37 +00:00
yunion-ci-robot
778363e732 Merge pull request #649 from yunion-ci-robot/cherry-pick-648-to-release/2.9.0
[release/2.9.0] fix: use db.FetchModelObjects to batch Query objects
2019-04-26 21:08:14 +08:00
Qiu Jian
3549907e75 fix: use db.FetchModelObjects to batch Query objects 2019-04-26 07:46:29 +00:00
yunion-ci-robot
15222c3520 Merge pull request #641 from yunion-ci-robot/cherry-pick-628-to-release/2.9.0
[release/2.9.0] Azure: 修复因系统盘大小导致重装系统失败
2019-04-26 02:08:12 +08:00
yunion-ci-robot
2f82b6d493 Merge pull request #642 from yunion-ci-robot/cherry-pick-634-to-release/2.9.0
[release/2.9.0] 手动同步的也更新last_auto_sync时间
2019-04-26 02:07:14 +08:00
ioito
7f5eefebc6 手动同步的也更新last_auto_sync时间 2019-04-25 16:42:34 +00:00
ioito
1d6bfd28eb Azure: 修复因系统盘大小导致重装系统失败 2019-04-25 16:42:30 +00:00
yunion-ci-robot
b9db1e0264 Merge pull request #637 from yunion-ci-robot/cherry-pick-611-to-release/2.9.0
[release/2.9.0] baremetal schedule net bonding check
2019-04-26 00:42:16 +08:00
yunion-ci-robot
dbcf04e589 Merge pull request #635 from yunion-ci-robot/cherry-pick-633-to-release/2.9.0
[release/2.9.0] 避免返回不是id not found,导致network一直删除失败
2019-04-26 00:41:14 +08:00
Zexi
3adf64b303 baremetal schedule net bonding check 2019-04-25 16:40:25 +00:00
ioito
912acf5ea4 避免返回不是id not found,导致network一直删除失败 2019-04-25 16:39:25 +00:00
yunion-ci-robot
015b95a0ae Merge pull request #629 from yunion-ci-robot/cherry-pick-624-to-release/2.9.0
[release/2.9.0] cloud-init users支持加上default
2019-04-25 21:50:20 +08:00
ioito
8423e75793 cloud-init users支持加上default 2019-04-25 13:29:27 +00:00
yunion-ci-robot
279fb9bc10 Merge pull request #625 from yunion-ci-robot/cherry-pick-610-to-release/2.9.0
[release/2.9.0] 避免同步时删除vpc失败,导致不同步vpc底下资源
2019-04-25 21:04:16 +08:00
ioito
d3b0a1f2b8 避免同步时删除vpc失败,导致不同步vpc底下资源 2019-04-25 12:51:29 +00:00
yunion-ci-robot
c4cc91cf40 Merge pull request #612 from yunion-ci-robot/cherry-pick-609-to-release/2.9.0
[release/2.9.0] Hotfix/qj failed prepaid recycle vm 2.8.0
2019-04-25 20:24:12 +08:00
yunion-ci-robot
32c912f11e Merge pull request #617 from yunion-ci-robot/cherry-pick-613-to-release/2.9.0
[release/2.9.0] Azure: 修复虚拟机时未设置keypair路径
2019-04-25 19:00:14 +08:00
yunion-ci-robot
dde3fb8cc5 Merge pull request #621 from yunion-ci-robot/cherry-pick-614-to-release/2.9.0
[release/2.9.0] bugfix: field host_id not found
2019-04-25 18:59:12 +08:00
wanyaoqi
fff91e6f7c bugfix: filed host_id not found 2019-04-25 10:57:45 +00:00
ioito
749fe93dee Azure: 修复虚拟机时未设置keypair路径 2019-04-25 10:49:27 +00:00
yunion-ci-robot
8f7c87eb54 Merge pull request #615 from yunion-ci-robot/cherry-pick-608-to-release/2.9.0
[release/2.9.0] huawei import keypair & rebuild root & skus filter fix
2019-04-25 18:49:15 +08:00
TangBin
da229f6c8e huawei import keypair & rebuild root & skus filter fix 2019-04-25 10:41:27 +00:00
Qiu Jian
4b50da3fa1 update vendor 2019-04-25 08:29:25 +00:00
Qiu Jian
8c70c86baa fix: 1. network interface for prepaid-recycle VM incorrect 2. aliyun not support import image of RHEL 2019-04-25 08:29:25 +00:00
yunion-ci-robot
ff1b67b6a1 Merge pull request #607 from yunion-ci-robot/cherry-pick-605-to-release/2.9.0
[release/2.9.0] fix: baremetal server deploy auto restart not work
2019-04-25 11:15:11 +08:00
Zexi
e793065967 fix: baremetal server deploy auto restart not work 2019-04-25 03:07:29 +00:00
yunion-ci-robot
f0c6c7c146 Merge pull request #601 from yunion-ci-robot/cherry-pick-586-to-release/2.9.0
[release/2.9.0] 支持批量添加标签api
2019-04-24 23:00:12 +08:00
ioito
e8ea9ab63f 支持批量添加标签api 2019-04-24 14:58:46 +00:00
yunion-ci-robot
2027dfb01d Merge pull request #597 from yunion-ci-robot/cherry-pick-577-to-release/2.9.0
[release/2.9.0] Azure重装系统支持初始化密码
2019-04-24 22:25:15 +08:00
ioito
fe7ed5e8a9 修复typo错误 2019-04-24 14:13:33 +00:00
ioito
e6a66e67a5 重装系统支持初始化密码 2019-04-24 14:13:32 +00:00
yunion-ci-robot
9374ce776a Merge pull request #596 from yunion-ci-robot/cherry-pick-585-to-release/2.9.0
[release/2.9.0] hotfix: import from libvirt , use link replace mv
2019-04-24 22:08:14 +08:00
wanyaoqi
6b8a634ab4 import from libvirt link disk, do not move 2019-04-24 13:52:29 +00:00
yunion-ci-robot
e543b001b2 Merge pull request #595 from yunion-ci-robot/cherry-pick-591-to-release/2.9.0
[release/2.9.0] fix: prepaid recycle host not check storage types
2019-04-24 20:59:12 +08:00
Zexi
35685580a9 fix: prepaid recycle host not check storage types 2019-04-24 12:55:44 +00:00
yunion-ci-robot
cb892f79e6 Merge pull request #574 from swordqiu/automated-cherry-pick-of-#525-upstream-release-2.9.0
Automated cherry pick of #525: fix: clearn up codes that impacted by query.Count return value changes
2019-04-24 19:23:11 +08:00
Qiu Jian
b838d0d00a update query.Count to query.CountWithError 2019-04-24 18:53:29 +08:00
Qiu Jian
1d8b7857b0 update vendor 2019-04-24 18:53:29 +08:00
Qiu Jian
c993fba16c fix: clearn up codes that impacted by query.Count return value changes 2019-04-24 18:53:28 +08:00
yunion-ci-robot
1da586c554 Merge pull request #588 from yunion-ci-robot/cherry-pick-587-to-release/2.9.0
[release/2.9.0] fix: validate baremetal raid config
2019-04-24 18:43:11 +08:00
Zexi
9915a78d05 fix: validate baremetal raid config 2019-04-24 10:41:26 +00:00
yunion-ci-robot
be5a9d174a Merge pull request #582 from yunion-ci-robot/cherry-pick-581-to-release/2.9.0
[release/2.9.0] fix: baremetal server create params not override disks
2019-04-24 12:19:13 +08:00
Zexi
6f92ceb4d3 fix: baremetal server create params not override disks 2019-04-24 04:13:23 +00:00
yunion-ci-robot
8f847d6797 Merge pull request #580 from yunion-ci-robot/cherry-pick-578-to-release/2.9.0
[release/2.9.0] 新增编译:host baremetal-agent 两个 rpm
2019-04-24 10:11:12 +08:00
Zhang Dongliang
c3c64567cd 新增编译:host baremetal-agent 两个 rpm 2019-04-24 02:09:02 +00:00
yunion-ci-robot
5055e1e95d Merge pull request #575 from yunion-ci-robot/cherry-pick-558-to-release/2.9.0
[release/2.9.0] fix: convert billingcycle to aliyun renew period error
2019-04-23 17:33:12 +08:00
Qiu Jian
c875905f26 fix: convert billingcycle to aliyun renew period error 2019-04-23 09:31:22 +00:00
yunion-ci-robot
5f50073b46 Merge pull request #569 from yunion-ci-robot/cherry-pick-557-to-release/2.9.0
[release/2.9.0] feature: server migrate add auto start
2019-04-23 17:28:12 +08:00
yunion-ci-robot
ded76dadd2 Merge pull request #568 from ioito/automated-cherry-pick-of-#535-upstream-release-2.9.0
Automated cherry pick of #535: 同步公有云资源创建时间
2019-04-23 17:12:14 +08:00
yunion-ci-robot
f20c4d7c0d Merge pull request #572 from yunion-ci-robot/cherry-pick-549-to-release/2.9.0
[release/2.9.0] Bugfix/ningyu meteralert project support
2019-04-23 17:04:11 +08:00
ningyu
b952652813 fix: 余额/消费报警引入了项目归属的概念,在创建、列出规则时都需要指定是哪个项目 2019-04-23 09:01:26 +00:00
yunion-ci-robot
bcf0f8729b Merge pull request #565 from yunion-ci-robot/cherry-pick-477-to-release/2.9.0
[release/2.9.0] aws rebuild root ignore password/key
2019-04-23 16:57:12 +08:00
yunion-ci-robot
2824683687 Merge pull request #564 from yunion-ci-robot/cherry-pick-531-to-release/2.9.0
[release/2.9.0] 避免qcloud password和keypair冲突
2019-04-23 16:50:15 +08:00
wanyaoqi
8cd748ba26 server migrate add auto start 2019-04-23 08:49:22 +00:00
ioito
66ba5c3e0e 同步公有云资源创建时间 2019-04-23 16:47:09 +08:00
tangbin
29d1cedf80 string format bugfix 2019-04-23 08:43:19 +00:00
TangBin
4371e6fb58 aws rebuild root ignore password/key 2019-04-23 08:43:19 +00:00
ioito
191550e89a 避免qcloud password和keypair冲突 2019-04-23 08:41:59 +00:00
yunion-ci-robot
c257ddda97 Merge pull request #560 from yunion-ci-robot/cherry-pick-537-to-release/2.9.0
[release/2.9.0] ip子网支持city过滤
2019-04-23 16:37:11 +08:00
yunion-ci-robot
c6205d6728 Merge pull request #563 from yunion-ci-robot/cherry-pick-536-to-release/2.9.0
[release/2.9.0] bugfix: fix aliyun snapshot delete failed, delete linked images first
2019-04-23 16:34:11 +08:00
wanyaoqi
83dff1843f fix aliyun snapshot delete failed, delete linked images first 2019-04-23 08:31:19 +00:00
ioito
29a23277c6 ip子网支持city过滤 2019-04-23 08:25:38 +00:00
yunion-ci-robot
5e28ea2833 Merge pull request #551 from yunion-ci-robot/cherry-pick-550-to-release/2.9.0
[release/2.9.0] 修复azure拼写错误
2019-04-23 15:28:11 +08:00
yunion-ci-robot
2e007249fa Merge pull request #555 from yunion-ci-robot/cherry-pick-538-to-release/2.9.0
[release/2.9.0] bugfix: fix query networks not set model manager
2019-04-23 14:13:12 +08:00
wanyaoqi
c57d2939ab fix query networks not set model manager 2019-04-23 06:10:28 +00:00
ioito
148aad03c1 修复azure拼写错误 2019-04-23 05:54:26 +00:00
yunion-ci-robot
489434b4e1 Merge pull request #545 from yunion-ci-robot/cherry-pick-539-to-release/2.9.0
[release/2.9.0] loadbalancernetwork: 支持lbnetwork-list --details
2019-04-22 23:34:14 +08:00
yunion-ci-robot
4130b49bc1 Merge pull request #546 from yunion-ci-robot/cherry-pick-540-to-release/2.9.0
[release/2.9.0] fix: domain-config-update rpc method panic
2019-04-22 23:32:12 +08:00
Zexi
ad4ce0bc17 fix: domain-config-update rpc method panic 2019-04-22 15:03:25 +00:00
Yousong Zhou
a8a0ee90ff loadbalancernetwork: 支持lbnetwork-list --details 2019-04-22 15:03:21 +00:00
yunion-ci-robot
60f964a8d5 Merge pull request #542 from yunion-ci-robot/cherry-pick-541-to-release/2.9.0
[release/2.9.0] bugfix: fix host clean recycle bin
2019-04-22 21:14:13 +08:00
wanyaoqi
c76aa7b6f9 fix host clean recycle bin 2019-04-22 12:50:31 +00:00
708 changed files with 20996 additions and 8697 deletions

53
Gopkg.lock generated
View File

@@ -524,6 +524,14 @@
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
version = "v1.4.7"
[[projects]]
digest = "1:2cd7915ab26ede7d95b8749e6b1f933f1c6d5398030684e6505940a10f31cfda"
name = "github.com/ghodss/yaml"
packages = ["."]
pruneopts = "UT"
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:36fe9527deed01d2a317617e59304eb2c4ce9f8a24115bcc5c2e37b3aee5bae4"
@@ -533,9 +541,10 @@
revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae"
[[projects]]
digest = "1:ff09f03ca12c4d23c28c596eb0738745e36c1cac111f62f64819210f40607cd2"
digest = "1:d5083934eb25e45d17f72ffa86cae3814f4a9d6c073c4f16b64147169b245606"
name = "github.com/gin-gonic/gin"
packages = [
".",
"binding",
"json",
"render",
@@ -1071,12 +1080,12 @@
version = "v2.0.7"
[[projects]]
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
branch = "master"
digest = "1:deff41c4160cc5b487a1d1a69a58925f2d3ac11befa0692b50e76940594e20f5"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = "UT"
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
revision = "27936f6d90f9c8e1145f11ed52ffffbfdb9e0af7"
[[projects]]
branch = "master"
@@ -1497,14 +1506,6 @@
revision = "df014850f6dee74ba2fc94874043a9f3f75fbfd8"
version = "v1.17.0"
[[projects]]
digest = "1:2655728699af00d823b0a68bd7169fd241a30c04252f456b34421908701b9c3f"
name = "gopkg.in/gin-gonic/gin.v1"
packages = ["."]
pruneopts = "UT"
revision = "d459835d2b077e44f7c9b453505ee29881d5d12d"
version = "v1.2"
[[projects]]
digest = "1:cbc72c4c4886a918d6ab4b95e347ffe259846260f99ebdd8a198c2331cf2b2e9"
name = "gopkg.in/go-playground/validator.v8"
@@ -1705,28 +1706,29 @@
[[projects]]
branch = "master"
digest = "1:53c214ff8c2fd57db0962140b9a5e57b01b63066e7de7fe6897a633d15b78248"
digest = "1:f044fe02305a360710bcb0626b870599537514da95c9d4f4cd31df0b4c017e5f"
name = "yunion.io/x/jsonutils"
packages = ["."]
pruneopts = "UT"
revision = "028b9007e455103eabacf3e6d71b5ce5060c3984"
revision = "a964e1e8a05199146284389fe6ef2d1eac2744b4"
[[projects]]
branch = "master"
digest = "1:b098c5b757b7622dfeed71f9cdcf0621a42051b88967286b0e1bcfb8a910fc86"
digest = "1:a872813eff1f3d353a1e4e64d745ac07387ed52cbc4cc2f6180272a7df7f21d1"
name = "yunion.io/x/log"
packages = [
".",
"hooks",
]
pruneopts = "UT"
revision = "71a36f55dcfcfa2c8b2477c339e2c7ebd78c731d"
revision = "9f6483a7103dc7b5012ae7aad2c74728e02cf650"
[[projects]]
branch = "master"
digest = "1:30ca06466aebad8751130956f96267bc520af0991990522109d4250086e3ae83"
digest = "1:c09298fb61e83dae28b08222e20f31bd109f93c50a29517a17edcc5a5666bd1a"
name = "yunion.io/x/pkg"
packages = [
"errors",
"gotypes",
"prettytable",
"trace",
@@ -1751,30 +1753,29 @@
"util/stringutils",
"util/timeutils",
"util/trace",
"util/ttlpool",
"util/version",
"util/wait",
"util/workqueue",
"utils",
]
pruneopts = "UT"
revision = "fa6430d86cfb0b2b3cc6ea20bab3b4618186234b"
revision = "b564cfdcc2247b3f6f6bc4e818b44f08d82dc660"
[[projects]]
branch = "master"
digest = "1:29f0a99ba079309ef8c82def5b9c452d0871837780ee702d7ae7c1ebe47478b0"
digest = "1:f7386c58a1e94eddbca9b8a95167ba7b4bc7d8dfea40a01261f7443757eafb25"
name = "yunion.io/x/sqlchemy"
packages = ["."]
pruneopts = "UT"
revision = "5e43c9cfbb8eb2870882b87d3ab429062d69be2b"
revision = "cfa59aeabbfe47c910920a2e1d61e1eaddd92ec5"
[[projects]]
branch = "master"
digest = "1:cfa79b54c4ec8d1fe6b1599846b3975c50212f58114d807a6db69bbee5a16b7a"
digest = "1:d91515edf1e995676f635f39ed5445e45fd3d176c71546744b11cba7e0126421"
name = "yunion.io/x/structarg"
packages = ["."]
pruneopts = "UT"
revision = "5b725f46d67547e7fb603b2118eddc5358ac2a39"
revision = "115bed041de33bdf3a5be5281d4a6b06607c82d8"
[solve-meta]
analyzer-name = "dep"
@@ -1835,6 +1836,7 @@
"github.com/coredns/coredns/request",
"github.com/fatih/color",
"github.com/fsnotify/fsnotify",
"github.com/gin-gonic/gin",
"github.com/go-sql-driver/mysql",
"github.com/golang-plus/errors",
"github.com/golang-plus/uuid",
@@ -1855,6 +1857,7 @@
"github.com/moul/http2curl",
"github.com/nelsonken/cos-go-sdk-v5/cos",
"github.com/pierrec/lz4",
"github.com/pkg/errors",
"github.com/serialx/hashring",
"github.com/shirou/gopsutil/cpu",
"github.com/shirou/gopsutil/host",
@@ -1882,7 +1885,6 @@
"golang.org/x/net/bpf",
"golang.org/x/net/ipv4",
"golang.org/x/sys/unix",
"gopkg.in/gin-gonic/gin.v1",
"gopkg.in/yaml.v2",
"k8s.io/api/core/v1",
"k8s.io/apimachinery/pkg/api/errors",
@@ -1895,6 +1897,8 @@
"k8s.io/kubernetes/pkg/scheduler/api/v1",
"yunion.io/x/jsonutils",
"yunion.io/x/log",
"yunion.io/x/log/hooks",
"yunion.io/x/pkg/errors",
"yunion.io/x/pkg/gotypes",
"yunion.io/x/pkg/prettytable",
"yunion.io/x/pkg/trace",
@@ -1917,7 +1921,6 @@
"yunion.io/x/pkg/util/stringutils",
"yunion.io/x/pkg/util/timeutils",
"yunion.io/x/pkg/util/trace",
"yunion.io/x/pkg/util/ttlpool",
"yunion.io/x/pkg/util/version",
"yunion.io/x/pkg/util/wait",
"yunion.io/x/pkg/util/workqueue",

View File

@@ -188,6 +188,10 @@
branch = "master"
name = "yunion.io/x/sqlchemy"
[[constraint]]
branch = "master"
name = "github.com/pkg/errors"
[[constraint]]
branch = "master"
name = "yunion.io/x/structarg"

View File

@@ -1,3 +1,4 @@
# Yunion OneCloud
[![CircleCI](https://circleci.com/gh/yunionio/onecloud.svg?style=svg)](https://circleci.com/gh/yunionio/onecloud) [![Build Status](https://travis-ci.org/yunionio/onecloud.svg?branch=master)](https://travis-ci.org/yunionio/onecloud)
[![Go Report Card](https://goreportcard.com/badge/github.com/yunionio/onecloud)](https://goreportcard.com/report/github.com/yunionio/onecloud)

View File

@@ -0,0 +1 @@
DESCRIPTION="Baremetal Agent Command Line Utility"

1
build/host/vars Normal file
View File

@@ -0,0 +1 @@
DESCRIPTION="Yunion Host Command Line Utility"

View File

@@ -1 +1 @@
您的{{ .hypervisor }}主机{{ .name }}的系统盘已经重置成功,{{ if .account }}初始帐号为{{ .account }}{{ end }}{{ if .keypair }}访问密钥为{{ .keypair }}{{ end }}{{ if .password }}初始密码为{{ .password }}{{ end }}请使用{{ if .windows }}远程桌面连接器(RDC){{ else }}SSH{{ end }}或控制面板控制台访问云主机。
您的{{ .hypervisor }}主机{{ .name }}重装系统成功,{{ if .account }}初始帐号为{{ .account }}{{ end }}{{ if .keypair }}访问密钥为{{ .keypair }}{{ end }}{{ if .password }}初始密码为{{ .password }}{{ end }}请使用{{ if .windows }}远程桌面连接器(RDC){{ else }}SSH{{ end }}或控制面板控制台访问云主机。

View File

@@ -1 +1 @@
{{ .hypervisor }}主机{{ .name }}的系统盘重置成功
{{ .hypervisor }}主机{{ .name }}重装系统成功

View File

@@ -16,8 +16,11 @@ package main
import (
"yunion.io/x/onecloud/pkg/baremetal/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.New().StartService()
}

View File

@@ -156,6 +156,17 @@ func init() {
return nil
})
R(&options.SUcloudCloudAccountCreateOptions{}, "cloud-account-create-ucloud", "Create a Ucloud cloud account", func(s *mcclient.ClientSession, args *options.SUcloudCloudAccountCreateOptions) error {
params := jsonutils.Marshal(args)
params.(*jsonutils.JSONDict).Add(jsonutils.NewString("Ucloud"), "provider")
result, err := modules.Cloudaccounts.Create(s, params)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudaccountUpdateOptions struct {
ID string `help:"ID or Name of cloud account"`
Name string `help:"New name to update"`

View File

@@ -37,7 +37,7 @@ func init() {
Occupied bool `help:"show occupid host" json:"-"`
Enabled bool `help:"Show enabled host only" json:"-"`
Disabled bool `help:"Show disabled host only" json:"-"`
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei"`
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei|ucloud"`
AnyMac string `help:"Mac matches one of the host's interface"`
IsBaremetal *bool `help:"filter host list by is_baremetal=true|false"`
@@ -48,6 +48,8 @@ func init() {
Hypervisor string `help:"filter hosts by hypervisor"`
StorageNotAttached bool `help:"List hosts not attach specified storage"`
options.BaseListOptions
}
R(&HostListOptions{}, "host-list", "List hosts", func(s *mcclient.ClientSession, opts *HostListOptions) error {
@@ -465,6 +467,7 @@ func init() {
MAC string `help:"Default MAC address of baremetal"`
Rack string `help:"Rack number of baremetal"`
Slots string `help:"Slots number of baremetal"`
IpmiUser string `help:"IPMI user name"`
IpmiPasswd string `help:"IPMI user password"`
IpmiAddr string `help:"IPMI IP address"`
}
@@ -479,6 +482,9 @@ func init() {
if len(args.Slots) > 0 {
params.Add(jsonutils.NewString(args.Slots), "slots")
}
if len(args.IpmiUser) > 0 {
params.Add(jsonutils.NewString(args.IpmiUser), "ipmi_username")
}
if len(args.IpmiPasswd) > 0 {
params.Add(jsonutils.NewString(args.IpmiPasswd), "ipmi_password")
}

View File

@@ -81,4 +81,5 @@ func init() {
printObject(lbbackendgroup)
return nil
})
}

View File

@@ -29,7 +29,7 @@ func init() {
Network string `help:"ID or Name of network"`
Ip string `help:"search the IP address"`
}
R(&LoadbalancerNetworkListOptions{}, "loadbalancer-network-list", "List loadbalancer network pairs", func(s *mcclient.ClientSession, args *LoadbalancerNetworkListOptions) error {
R(&LoadbalancerNetworkListOptions{}, "lbnetwork-list", "List loadbalancer network pairs", func(s *mcclient.ClientSession, args *LoadbalancerNetworkListOptions) error {
var params *jsonutils.JSONDict
{
var err error
@@ -57,5 +57,4 @@ func init() {
printList(result, modules.Loadbalancernetworks.GetColumns(s))
return nil
})
}

View File

@@ -98,4 +98,5 @@ func init() {
printObject(lb)
return nil
})
}

View File

@@ -28,32 +28,23 @@ func init() {
* 创建一条报警规则
*/
type MeterAlertCreateOptions struct {
TYPE string `help:"Alert rule type" choices:"balance|resFee|monthFee"`
THRESHOLD float64 `help:"Threshold value of the metric"`
COMPARATOR string `help:"Comparison operator for join expressions" choices:">|<|>=|<=|=|!="`
RECIPIENTS string `help:"Comma separated recipient ID"`
LEVEL string `help:"Alert level" choices:"normal|important|fatal"`
CHANNEL string `help:"Ways to send an alarm" choices:"email|mobile"`
Type string `help:"Alert rule type" required:"true" choices:"balance|resFee|monthFee"`
Threshold float64 `help:"Threshold value of the metric" required:"true"`
Comparator string `help:"Comparison operator for join expressions" required:"true" choices:">|<|>=|<=|=|!="`
Recipients string `help:"Comma separated recipient ID" required:"true"`
Level string `help:"Alert level" required:"true" choices:"normal|important|fatal"`
Channel string `help:"Ways to send an alarm" required:"true" choices:"email|mobile"`
Provider string `help:"Name of the cloud platform"`
AccountId string `help:"ID of the cloud platform"`
ProjectId string `help:"ID of the project" required:"true"`
}
R(&MeterAlertCreateOptions{}, "meteralert-create", "Create a meter alert rule", func(s *mcclient.ClientSession, args *MeterAlertCreateOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.TYPE), "type")
params.Add(jsonutils.NewFloat(args.THRESHOLD), "threshold")
params.Add(jsonutils.NewString(args.COMPARATOR), "comparator")
params.Add(jsonutils.NewString(args.RECIPIENTS), "recipients")
params.Add(jsonutils.NewString(args.LEVEL), "level")
params.Add(jsonutils.NewString(args.CHANNEL), "channel")
if len(args.Provider) > 0 {
params.Add(jsonutils.NewString(args.Provider), "provider")
}
if len(args.AccountId) > 0 {
params.Add(jsonutils.NewString(args.AccountId), "account_id")
params, err := options.StructToParams(args)
if err != nil {
return err
}
rst, err := modules.MeterAlert.Create(s, params)
if err != nil {
return err
}
@@ -103,27 +94,15 @@ func init() {
Type string `help:"Alarm rule type" choices:"balance|resFee|monthFee"`
CloudProvider string `help:"Name of cloud provider, case sensitive"`
AccountId string `help:"Cloud account ID"`
ProjectId string `help:"ID of the project" required:"true"`
options.BaseListOptions
}
R(&MeterAlertListOptions{}, "meteralert-list", "List meter alert", func(s *mcclient.ClientSession, args *MeterAlertListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
if len(args.Type) > 0 {
params.Add(jsonutils.NewString(args.Type), "type")
}
if len(args.CloudProvider) > 0 {
params.Add(jsonutils.NewString(args.CloudProvider), "provider")
}
if len(args.AccountId) > 0 {
params.Add(jsonutils.NewString(args.AccountId), "account_id")
}
params, err := options.ListStructToParams(args)
if err != nil {
return err
}
result, err := modules.MeterAlert.List(s, params)
if err != nil {
return err

View File

@@ -34,6 +34,8 @@ func init() {
Host string `help:"search networks attached to a host"`
Vpc string `help:"search networks belongs to a VPC"`
Region string `help:"search networks belongs to a CloudRegion" json:"cloudregion"`
City string `help:"search networks belongs to a city"`
Usable *bool `help:"search usable networks"`
ServerType string `help:"search networks belongs to a ServerType" choices:"guest|baremetal|container|pxe|ipmi"`
}
R(&NetworkListOptions{}, "network-list", "List networks", func(s *mcclient.ClientSession, opts *NetworkListOptions) error {

View File

@@ -39,10 +39,10 @@ func init() {
typ, _ := routeObj.GetString("type")
cidr, _ := routeObj.GetString("cidr")
next_hop_type, _ := routeObj.GetString("next_hop_type")
next_hop, _ := routeObj.GetString("next_hop")
next_hop_id, _ := routeObj.GetString("next_hop_id")
route := fmt.Sprintf("%8s: %18s %s", typ, cidr, next_hop_type)
if len(next_hop) > 0 {
route += fmt.Sprintf(":%s", next_hop)
if next_hop_id != "" {
route += fmt.Sprintf(":%s", next_hop_id)
}
routes = append(routes, route)
}

View File

@@ -107,6 +107,19 @@ func init() {
return nil
})
type SchedulerCleanCacheOptions struct {
HostId string `help:"ID of host" short-token:"h"`
SessionId string `help:"Session id" short-token:"s"`
}
R(&SchedulerCleanCacheOptions{}, "scheduler-clean-cache", "Clean scheduler hosts cache",
func(s *mcclient.ClientSession, args *SchedulerCleanCacheOptions) error {
err := modules.SchedManager.CleanCache(s, args.HostId, args.SessionId)
if err != nil {
return err
}
return nil
})
type SchedulerHistoryListOptions struct {
Limit int `default:"50" help:"Page limit"`
Offset int `default:"0" help:"Page offset"`

View File

@@ -18,9 +18,11 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
yaml "gopkg.in/yaml.v2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -101,6 +103,32 @@ func init() {
return nil
})
R(&options.ServerBatchMetadataOptions{}, "server-batch-add-tag", "add tags for some server", func(s *mcclient.ClientSession, opts *options.ServerBatchMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.Servers.PerformClassAction(s, "batch-user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ServerBatchMetadataOptions{}, "server-batch-set-tag", "Set tags for some server", func(s *mcclient.ClientSession, opts *options.ServerBatchMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.Servers.PerformClassAction(s, "batch-set-user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.ServerMetadataOptions{}, "server-add-tag", "Set tag of a server", func(s *mcclient.ClientSession, opts *options.ServerMetadataOptions) error {
params, err := opts.Params()
if err != nil {
@@ -818,34 +846,101 @@ func init() {
})
type ServersImportFromLibvirtOptions struct {
CONFIG_FILE string `help:"JSON file describing servers from libvirt, e.g.
{'hosts':
[
{
'servers': [
{
'mac_ip': {'mac1': 'ip1', ...}
},
],
'xml_file_path': '/etc/libvirt/qemu',
'host_ip': '192.168.1.100',
},
],
}
"`
CONFIG_FILE string `help:"File Path describing servers from libvirt"`
}
type Servers struct {
Mac string `yaml:"mac"`
Ip string `yaml:"ip"`
}
type Hosts struct {
HostIp string `yaml:"host_ip"`
XmlFilePath string `yaml:"xml_file_path"`
MonitorPath string `yaml:"monitor_path"`
Servers []Servers `yaml:"servers"`
}
type LibvirtImportOptions struct {
Hosts []Hosts `yaml:"hosts"`
}
R(&ServersImportFromLibvirtOptions{}, "servers-import-from-libvirt", "Import servers from libvrt", func(s *mcclient.ClientSession, args *ServersImportFromLibvirtOptions) error {
rawConfig, err := ioutil.ReadFile(args.CONFIG_FILE)
var (
rawConfig []byte
err error
)
rawConfig, err = ioutil.ReadFile(args.CONFIG_FILE)
if err != nil {
return fmt.Errorf("Read file error: %s", err)
return fmt.Errorf("Read config file %s error: %s", args.CONFIG_FILE, err)
}
config := &compute.SLibvirtImportConfig{}
err = json.Unmarshal(rawConfig, config)
if err != nil {
return fmt.Errorf("Parse config error %s", err)
var (
params []jsonutils.JSONObject
config = &compute.SLibvirtImportConfig{}
)
// Try parse as json first
{
err = json.Unmarshal(rawConfig, config)
if err != nil {
goto YAML
}
for i := 0; i < len(config.Hosts); i++ {
if nIp := net.ParseIP(config.Hosts[i].HostIp); nIp == nil {
return fmt.Errorf("Parse host ip %s failed", config.Hosts[i].HostIp)
}
for _, server := range config.Hosts[i].Servers {
for mac, ip := range server.MacIp {
if _, err := net.ParseMAC(mac); err != nil {
return fmt.Errorf("Parse mac %s error %s", mac, err)
}
if nIp := net.ParseIP(ip); nIp == nil {
return fmt.Errorf("Parse ip %s failed", ip)
}
}
}
}
goto REQUEST
}
params, err := jsonutils.Marshal(config.Hosts).GetArray()
YAML: // Try Parse as yaml
{
yamlConfig := &LibvirtImportOptions{}
err = yaml.Unmarshal(rawConfig, yamlConfig)
if err != nil {
return err
}
config.Hosts = make([]compute.SLibvirtHostConfig, len(yamlConfig.Hosts))
for i := 0; i < len(yamlConfig.Hosts); i++ {
if nIp := net.ParseIP(yamlConfig.Hosts[i].HostIp); nIp == nil {
return fmt.Errorf("Parse host ip %s failed", yamlConfig.Hosts[i].HostIp)
}
config.Hosts[i].HostIp = yamlConfig.Hosts[i].HostIp
config.Hosts[i].XmlFilePath = yamlConfig.Hosts[i].XmlFilePath
config.Hosts[i].Servers = make([]compute.SLibvirtServerConfig, len(yamlConfig.Hosts[i].Servers))
for j := 0; j < len(yamlConfig.Hosts[i].Servers); j++ {
config.Hosts[i].Servers[j].MacIp = make(map[string]string)
mac := yamlConfig.Hosts[i].Servers[j].Mac
_, err := net.ParseMAC(mac)
if err != nil {
return fmt.Errorf("Parse mac address %s error %s", mac, err)
}
ip := yamlConfig.Hosts[i].Servers[j].Ip
nIp := net.ParseIP(ip)
if len(nIp) == 0 {
return fmt.Errorf("Parse ip address %s failed", ip)
}
config.Hosts[i].Servers[j].MacIp[mac] = ip
}
}
}
REQUEST:
params, err = jsonutils.Marshal(config.Hosts).GetArray()
if err != nil {
return err
}

View File

@@ -93,4 +93,20 @@ func init() {
return nil
})
type SnapshotCreateOptions struct {
Disk string `help:"Id of disk to take snapshot" json:"disk" required:"true"`
NAME string `help:"Name of snapshot" json:"name"`
}
R(&SnapshotCreateOptions{}, "snapshot-create", "Create a snapshot", func(s *mcclient.ClientSession, args *SnapshotCreateOptions) error {
params, err := options.StructToParams(args)
if err != nil {
return err
}
snapshot, err := modules.Snapshots.Create(s, params)
if err != nil {
return err
}
printObject(snapshot)
return nil
})
}

View File

@@ -94,7 +94,7 @@ func init() {
ZONE string `help:"Zone id of storage"`
Capacity int64 `help:"Capacity of the Storage"`
MediumType string `help:"Medium type, either ssd or rotate" choices:"ssd|rotate"`
StorageType string `help:"Storage type" choices:"local|nas|vsan|rbd|nfs|baremetal"`
StorageType string `help:"Storage type" choices:"local|nas|vsan|rbd|nfs|gpfs|baremetal"`
MonHost string `help:"Ceph mon_host config"`
Key string `help:"Ceph key config"`
Pool string `help:"Ceph Poll Name"`

View File

@@ -14,8 +14,13 @@
package main
import "yunion.io/x/onecloud/pkg/cloudir/service"
import (
"yunion.io/x/onecloud/pkg/cloudir/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -14,8 +14,13 @@
package main
import "yunion.io/x/onecloud/pkg/cloutpost/service"
import (
"yunion.io/x/onecloud/pkg/cloutpost/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -88,7 +88,7 @@ func newClient(options *BaseOptions) (*esxi.SESXiClient, error) {
return nil, fmt.Errorf("Missing password")
}
return esxi.NewESXiClient("", "", options.Host, options.Port, options.Account, options.Password)
return esxi.NewESXiClient2("", "", options.Host, options.Port, options.Account, options.Password, false)
}
func main() {

View File

@@ -16,8 +16,11 @@ package main
import (
"yunion.io/x/onecloud/pkg/image/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -14,8 +14,13 @@
package main
import "yunion.io/x/onecloud/pkg/hostimage"
import (
"yunion.io/x/onecloud/pkg/hostimage"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
hostimage.StartService()
}

View File

@@ -14,9 +14,18 @@
package main
import "yunion.io/x/onecloud/pkg/hostman"
import (
"yunion.io/x/onecloud/pkg/cloudcommon/service"
"yunion.io/x/onecloud/pkg/hostman"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
var srv = hostman.SHostService{}
defer atexit.Handle()
var srv = &hostman.SHostService{}
srv.SServiceBase = &service.SServiceBase{
Service: srv,
}
srv.StartService()
}

View File

@@ -26,9 +26,12 @@ import (
app_common "yunion.io/x/onecloud/pkg/cloudcommon/app"
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
"yunion.io/x/onecloud/pkg/lbagent"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
opts := &lbagent.Options{}
commonOpts := &opts.CommonOptions
{

View File

@@ -16,8 +16,11 @@ package main
import (
"yunion.io/x/onecloud/pkg/logger/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -34,6 +34,7 @@ type BaseOptions struct {
Password string `help:"Password" default:"$OPENSTACK_PASSWORD"`
Project string `help:"Project" default:"$OPENSTACK_PROJECT"`
EndpointType string `help:"Project" default:"$OPENSTACK_ENDPOINT_TYPE|internal"`
DomainName string `help:"DomainName" default:"$OPENSTACK_DOMAIN_NAME"`
RegionID string `help:"RegionId" default:"$OPENSTACK_REGION_ID"`
SUBCOMMAND string `help:"openstackcli subcommand" subcommand:"true"`
}
@@ -91,7 +92,7 @@ func newClient(options *BaseOptions) (*openstack.SRegion, error) {
return nil, fmt.Errorf("Missing Password")
}
cli, err := openstack.NewOpenStackClient("", "", options.AuthURL, options.Username, options.Password, options.Project, options.EndpointType, options.Debug)
cli, err := openstack.NewOpenStackClient("", "", options.AuthURL, options.Username, options.Password, options.Project, options.EndpointType, options.DomainName, options.Debug)
if err != nil {
return nil, err
}

View File

@@ -34,6 +34,7 @@ import (
_ "github.com/mholt/caddy/startupshutdown"
_ "yunion.io/x/onecloud/pkg/dns"
"yunion.io/x/onecloud/pkg/util/atexit"
)
var directives = []string{
@@ -58,5 +59,7 @@ func init() {
}
func main() {
defer atexit.Handle()
coremain.Run()
}

View File

@@ -16,8 +16,11 @@ package main
import (
"yunion.io/x/onecloud/pkg/compute/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -15,17 +15,20 @@
package main
import (
"os"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/scheduler/service"
"yunion.io/x/onecloud/pkg/util/atexit"
)
func main() {
exitCode := 0
defer func() {
atexit.Exit(exitCode)
}()
if err := service.StartService(); err != nil {
log.Errorln(err)
os.Exit(-1)
exitCode = -1
}
os.Exit(0)
}

View File

@@ -33,6 +33,7 @@ import (
"yunion.io/x/pkg/util/version"
"yunion.io/x/structarg"
"yunion.io/x/onecloud/pkg/util/atexit"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/nodeid"
"yunion.io/x/onecloud/pkg/util/torrentutils"
@@ -62,6 +63,8 @@ func exitSignalHandlers(client *torrent.Client) {
}
func main() {
defer atexit.Handle()
options := Options{}
parser, err := structarg.NewArgumentParser(&options, "torrent-srv", "bit-torrent server", "2018")

132
cmd/ucloudcli/main.go Normal file
View File

@@ -0,0 +1,132 @@
package main
import (
"fmt"
"os"
"yunion.io/x/onecloud/pkg/util/ucloud"
"yunion.io/x/log"
"yunion.io/x/structarg"
"yunion.io/x/onecloud/pkg/util/shellutils"
_ "yunion.io/x/onecloud/pkg/util/ucloud/shell"
)
type BaseOptions struct {
Help bool `help:"Show help" default:"false"`
Debug bool `help:"Show debug" default:"false"`
AccessKey string `help:"Access key" default:"$UCLOUD_ACCESS_KEY"`
Secret string `help:"Secret" default:"$UCLOUD_SECRET"`
RegionId string `help:"RegionId" default:"$UCLOUD_REGION"`
ProjectId string `help:"ProjectId" default:"$UCLOUD_PROJECT"`
SUBCOMMAND string `help:"ucloudcli subcommand" subcommand:"true"`
}
func getSubcommandParser() (*structarg.ArgumentParser, error) {
parse, e := structarg.NewArgumentParser(&BaseOptions{},
"ucloudcli",
"Command-line interface to ucloud API.",
`See "ucloudcli help COMMAND" for help on a specific command.`)
if e != nil {
return nil, e
}
subcmd := parse.GetSubcommand()
if subcmd == nil {
return nil, fmt.Errorf("No subcommand argument.")
}
type HelpOptions struct {
SUBCOMMAND string `help:"sub-command name"`
}
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
if e != nil {
return e
} else {
fmt.Print(helpstr)
return nil
}
})
for _, v := range shellutils.CommandTable {
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
if e != nil {
return nil, e
}
}
return parse, nil
}
func showErrorAndExit(e error) {
log.Errorf("%s", e)
os.Exit(1)
}
func newClient(options *BaseOptions) (*ucloud.SRegion, error) {
if len(options.AccessKey) == 0 {
return nil, fmt.Errorf("Missing accessKey")
}
if len(options.Secret) == 0 {
return nil, fmt.Errorf("Missing secret")
}
account := ""
if len(options.ProjectId) > 0 {
account = options.AccessKey + "::" + options.ProjectId
} else {
account = options.AccessKey
}
cli, err := ucloud.NewUcloudClient("", "", account, options.Secret, options.Debug)
if err != nil {
return nil, err
}
region := cli.GetRegion(options.RegionId)
if region == nil {
return nil, fmt.Errorf("No such region %s", options.RegionId)
}
return region, nil
}
func main() {
parser, e := getSubcommandParser()
if e != nil {
showErrorAndExit(e)
}
e = parser.ParseArgs(os.Args[1:], false)
options := parser.Options().(*BaseOptions)
if options.Help {
fmt.Print(parser.HelpString())
} else {
subcmd := parser.GetSubcommand()
subparser := subcmd.GetSubParser()
if e != nil {
if subparser != nil {
fmt.Print(subparser.Usage())
} else {
fmt.Print(parser.Usage())
}
showErrorAndExit(e)
} else {
suboptions := subparser.Options()
if options.SUBCOMMAND == "help" {
e = subcmd.Invoke(suboptions)
} else {
var region *ucloud.SRegion
region, e = newClient(options)
if e != nil {
showErrorAndExit(e)
}
e = subcmd.Invoke(region, suboptions)
}
if e != nil {
showErrorAndExit(e)
}
}
}
}

View File

@@ -15,9 +15,12 @@
package main
import (
"yunion.io/x/onecloud/pkg/util/atexit"
"yunion.io/x/onecloud/pkg/webconsole/service"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -20,9 +20,12 @@ Yunion Conf Service
*/
import (
"yunion.io/x/onecloud/pkg/util/atexit"
"yunion.io/x/onecloud/pkg/yunionconf/service"
)
func main() {
defer atexit.Handle()
service.StartService()
}

View File

@@ -25,6 +25,7 @@ type SchedtagConfig struct {
Id string `json:"id"`
Strategy string `json:"strategy"`
Weight int `json:"weight"`
}
type NetworkConfig struct {

View File

@@ -0,0 +1,11 @@
package compute
type SGMapItem struct {
SGDeviceName string
HostNumber int
Bus int
SCSIId int
Lun int
Type int
LinuxDeviceName string
}

View File

@@ -12,6 +12,7 @@ const (
CLOUD_PROVIDER_SYNC_STATUS_QUEUED = "queued"
CLOUD_PROVIDER_SYNC_STATUS_SYNCING = "syncing"
CLOUD_PROVIDER_SYNC_STATUS_IDLE = "idle"
CLOUD_PROVIDER_SYNC_STATUS_ERROR = "error"
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
CLOUD_PROVIDER_VMWARE = "VMware"
@@ -23,15 +24,17 @@ const (
CLOUD_PROVIDER_OPENSTACK = "OpenStack"
CLOUD_PROVIDER_UCLOUD = "Ucloud"
CLOUD_PROVIDER_HEALTH_NORMAL = "normal" // 远端处于健康状态
CLOUD_PROVIDER_HEALTH_INSUFFICIENT = "insufficient" // 不足按需资源余额
CLOUD_PROVIDER_HEALTH_SUSPENDED = "suspended" // 远端处于冻结状态
CLOUD_PROVIDER_HEALTH_ARREARS = "arrears" // 远端处于欠费状态
CLOUD_PROVIDER_HEALTH_UNKNOWN = "unknown" // 未知状态,查询失败
CLOUD_PROVIDER_HEALTH_NORMAL = "normal" // 远端处于健康状态
CLOUD_PROVIDER_HEALTH_INSUFFICIENT = "insufficient" // 不足按需资源余额
CLOUD_PROVIDER_HEALTH_SUSPENDED = "suspended" // 远端处于冻结状态
CLOUD_PROVIDER_HEALTH_ARREARS = "arrears" // 远端处于欠费状态
CLOUD_PROVIDER_HEALTH_UNKNOWN = "unknown" // 未知状态,查询失败
CLOUD_PROVIDER_HEALTH_NO_PERMISSION = "no permission" // 没有权限获取账单信息
)
var (
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
CLOUD_PROVIDER_VALID_HEALTH_STATUS = []string{CLOUD_PROVIDER_HEALTH_NORMAL, CLOUD_PROVIDER_HEALTH_NO_PERMISSION}
CLOUD_PROVIDERS = []string{
CLOUD_PROVIDER_ONECLOUD,

View File

@@ -5,4 +5,138 @@ const (
CLOUD_REGION_STATUS_OUTOFSERVICE = "outofservice"
DEFAULT_REGION_ID = "default"
// 中国
CITY_QING_DAO = "Qingdao" //青岛
CITY_BEI_JING = "Beijing" //北京
CITY_ZHANG_JIA_KOU = "Zhangjiakou" //张家口
CITY_HU_HE_HAO_TE = "Huhehaote" //呼和浩特
CITY_HANG_ZHOU = "Hangzhou" //杭州
CITY_SHANG_HAI = "Shanghai" //上海
CITY_SHEN_ZHEN = "Shenzhen" //深圳
CITY_HONG_KONG = "Hongkong" //香港
CITY_NING_XIA = "Ningxia" //宁夏
CITY_GUANG_ZHOU = "Guangzhou" //广州
CITY_GUI_YANG = "Guiyang" //贵阳
CITY_TAIPEI = "Taipei" //台北市
CITY_KAOHSIUNG = "Kaohsiung" //高雄市
CITY_CHENG_DU = "Chengdu" //成都
CITY_CHONG_QING = "Chongqing" //重庆
// 日本
CITY_TOKYO = "Tokyo" //东京
CITY_OSAKA = "Osaka" //大阪市
// 新加坡
CITY_SINGAPORE = "Singapore" //新加坡
// 澳大利亚
CITY_SYDNEY = "Sydney" //悉尼
CITY_YARRALUMLA = "Yarralumla" //亚拉伦拉
CITY_MELBOURNE = "Melbourne" //墨尔本
// 马来西亚
CITY_KUALA_LUMPUR = "Kuala Lumpur" //吉隆坡
// 印度尼西亚
CITY_JAKARTA = "Jakarta" //雅加达
// 印度
CITY_MUMBAI = "Mumbai" //孟买
CITY_KANCHIPURAM = "Kanchipuram" //甘吉布勒姆
CITY_MAHARASHTRA = "Maharashtra" //马哈拉施特拉邦
// 美国
CITY_VIRGINIA = "Virginia" //弗吉尼亚
CITY_SILICONVALLEY = "Siliconvalley" //硅谷
CITY_OHIO = "Ohio" //俄亥俄州
CITY_N_VIRGINIA = "N. Virginia" //北弗吉尼亚
CITY_N_CALIFORNIA = "N. California" //北加州
CITY_OREGON = "Oregon" //俄勒冈州
CITY_LOS_ANGELES = "Los Angeles" //洛杉矶
CITY_SAN_FRANCISCO = "San Francisco" //旧金山
CITY_UTAH = "Utah" //犹他州
CITY_WASHINGTON = "Washington" //华盛顿
CITY_TEXAS = "Texas" //德克萨斯
CITY_CHICAGO = "Chicago" //芝加哥
CITY_IOWA = "Iowa" //爱荷华
CITY_US_GOV_WEST = "us-gov-west" //???
// 英国
CITY_LONDON = "London" //伦敦
CITY_HALTON = "Halton" //哈尔顿
CITY_WEST_SUSSEX = "West Sussex" //西苏塞克斯
// 阿拉伯联合酋长国
CITY_DUBAI = "Dubai" //迪拜
// 德国
CITY_FRANKFURT = "Frankfurt" //法兰克福
// 韩国
CITY_SEOUL = "Seoul" //首尔
CITY_BUSAN = "Busan" //釜山
// 加拿大
CITY_CANADA_CENTRAL = "Canada Central" //加拿大中部
CITY_QUEBEC = "Quebec" //魁北克市
CITY_TORONTO = "Toronto" //多伦多
// 爱尔兰
CITY_IRELAND = "Ireland" //爱尔兰
CITY_DUBLIN = "Dublin" //都柏林
// 法国
CITY_PARIS = "Paris" //巴黎
CITY_ALLIER = "Allier" //阿利埃河
CITY_TARN = "Tarn" //塔恩
// 瑞典
CITY_STOCKHOLM = "Stockholm" //斯德哥尔摩
// 巴西
CITY_SAO_PAULO = "Sao Paulo" //圣保罗
// 荷兰
CITY_HOLLAND = "Holland" //荷兰
// 南非
CITY_PRETORIA = "Pretoria" //比勒陀利亚
CITY_CAPE_TOWN = "Cape Town" //开普敦
// 泰国
CITY_BANGKOK = "Bangkok" //曼谷
// 俄罗斯
CITY_MOSCOW = "Moscow" //莫斯科
// 尼日利亚
CITY_LAGOS = "Lagos" //拉哥斯
// 越南
CITY_HO_CHI_MINH = "Ho Chi Minh" //???
COUNTRY_CODE_CN = "CN" //中国
COUNTRY_CODE_JP = "JP" //日本
COUNTRY_CODE_SG = "SG" //新加坡
COUNTRY_CODE_AU = "AU" //澳大利亚
COUNTRY_CODE_MY = "MY" //马来西亚
COUNTRY_CODE_ID = "ID" //印度尼西亚
COUNTRY_CODE_IN = "IN" //印度
COUNTRY_CODE_US = "US" //美国
COUNTRY_CODE_GB = "GB" //英国
COUNTRY_CODE_AE = "AE" //阿拉伯联合酋长国
COUNTRY_CODE_DE = "DE" //德国
COUNTRY_CODE_KR = "KR" //韩国
COUNTRY_CODE_CA = "CA" //加拿大
COUNTRY_CODE_IE = "IE" //爱尔兰
COUNTRY_CODE_FR = "FR" //法国
COUNTRY_CODE_SE = "SE" //瑞典
COUNTRY_CODE_BR = "BR" //巴西
COUNTRY_CODE_NL = "NL" //荷兰
COUNTRY_CODE_ZA = "ZA" //南非
COUNTRY_CODE_TH = "TH" //泰国
COUNTRY_CODE_RU = "RU" //俄罗斯
COUNTRY_CODE_NG = "NG" //尼日利亚
COUNTRY_CODE_VN = "VN" //越南
)

View File

@@ -51,4 +51,6 @@ const (
DISK_TYPE_VOLUME = "volume"
DISK_BACKING_IMAGE = "image"
DISK_SIZE_AUTOEXTEND = -1
)

View File

@@ -0,0 +1,5 @@
package compute
const (
ESXI_IMAGE_CACHE_TMP_PREFIX = "yunioncloud.imagecache"
)

View File

@@ -72,13 +72,13 @@ const (
VM_REBUILD_ROOT = "rebuild_root"
VM_REBUILD_ROOT_FAIL = "rebuild_root_fail"
VM_START_SNAPSHOT = "snapshot_start"
VM_SNAPSHOT = "snapshot"
VM_SNAPSHOT_DELETE = "snapshot_delete"
VM_BLOCK_STREAM = "block_stream"
VM_MIRROR_FAIL = "mirror_failed"
VM_SNAPSHOT_SUCC = "snapshot_succ"
VM_SNAPSHOT_FAILED = "snapshot_failed"
VM_START_SNAPSHOT = "snapshot_start"
VM_SNAPSHOT = "snapshot"
VM_SNAPSHOT_DELETE = "snapshot_delete"
VM_BLOCK_STREAM = "block_stream"
VM_BLOCK_STREAM_FAIL = "block_stream_fail"
VM_SNAPSHOT_SUCC = "snapshot_succ"
VM_SNAPSHOT_FAILED = "snapshot_failed"
VM_SYNCING_STATUS = "syncing"
VM_SYNC_CONFIG = "sync_config"
@@ -186,7 +186,8 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
}
const (
VM_AWS_DEFAULT_LOGIN_USER = "ec2user"
VM_AWS_DEFAULT_LOGIN_USER = "ec2user"
VM_AZURE_DEFAULT_LOGIN_USER = "toor"
VM_METADATA_APP_TAGS = "app_tags"
VM_METADATA_CREATE_PARAMS = "create_params"

View File

@@ -53,6 +53,7 @@ type SImportGuestDesc struct {
BootOrder string `json:"boot_order"`
IsSystem bool `json:"is_system"`
Description string `json:"description"`
MonitorPath string `json:"monitor_path"`
}
type SLibvirtServerConfig struct {
@@ -62,6 +63,7 @@ type SLibvirtServerConfig struct {
type SLibvirtHostConfig struct {
Servers []SLibvirtServerConfig `json:"servers"`
XmlFilePath string `json:"xml_file_path"`
MonitorPath string `json:"monitor_path"`
HostIp string `json:"host_ip"`
}

View File

@@ -74,6 +74,6 @@ const (
HostResourceTypeDedicated = "dedicated"
)
var HOST_TYPES = []string{HOST_TYPE_BAREMETAL, HOST_TYPE_HYPERVISOR, HOST_TYPE_ESXI, HOST_TYPE_KUBELET, HOST_TYPE_XEN, HOST_TYPE_ALIYUN, HOST_TYPE_AZURE, HOST_TYPE_AWS, HOST_TYPE_QCLOUD, HOST_TYPE_HUAWEI, HOST_TYPE_OPENSTACK}
var HOST_TYPES = []string{HOST_TYPE_BAREMETAL, HOST_TYPE_HYPERVISOR, HOST_TYPE_ESXI, HOST_TYPE_KUBELET, HOST_TYPE_XEN, HOST_TYPE_ALIYUN, HOST_TYPE_AZURE, HOST_TYPE_AWS, HOST_TYPE_QCLOUD, HOST_TYPE_HUAWEI, HOST_TYPE_OPENSTACK, HOST_TYPE_UCLOUD}
var NIC_TYPES = []string{NIC_TYPE_IPMI, NIC_TYPE_ADMIN}

View File

@@ -81,6 +81,7 @@ var LB_BACKENDGROUP_TYPE = choices.NewChoices(
)
const (
LB_ALIYUN_SPEC_SHAREABLE = "" //性能共享型
LB_ALIYUN_SPEC_S1_SMALL = "slb.s1.small"
LB_ALIYUN_SPEC_S2_SMALL = "slb.s2.small"
LB_ALIYUN_SPEC_S3_SMALL = "slb.s3.small"
@@ -95,6 +96,7 @@ const (
)
var LB_ALIYUN_SPECS = choices.NewChoices(
LB_ALIYUN_SPEC_SHAREABLE,
LB_ALIYUN_SPEC_S1_SMALL,
LB_ALIYUN_SPEC_S2_SMALL,
LB_ALIYUN_SPEC_S3_SMALL,
@@ -254,6 +256,7 @@ const (
LB_SCHEDULER_WLC = "wlc" // weighted least connection
LB_SCHEDULER_SCH = "sch" // source-ip-based consistent hash
LB_SCHEDULER_TCH = "tch" // 4-tuple-based consistent hash
LB_SCHEDULER_QCH = "qch"
)
var LB_SCHEDULER_TYPES = choices.NewChoices(
@@ -264,15 +267,32 @@ var LB_SCHEDULER_TYPES = choices.NewChoices(
LB_SCHEDULER_TCH,
)
var LB_ALIYUN_UDP_SCHEDULER_TYPES = choices.NewChoices(
LB_SCHEDULER_RR,
LB_SCHEDULER_WRR,
LB_SCHEDULER_WLC,
LB_SCHEDULER_SCH,
LB_SCHEDULER_TCH,
LB_SCHEDULER_QCH,
)
var LB_ALIYUN_COMMON_SCHEDULER_TYPES = choices.NewChoices(
LB_SCHEDULER_RR,
LB_SCHEDULER_WRR,
LB_SCHEDULER_WLC,
)
// TODO raw type
const (
LB_BACKEND_GUEST = "guest"
LB_BACKEND_HOST = "host"
LB_BACKEND_IP = "ip"
)
var LB_BACKEND_TYPES = choices.NewChoices(
LB_BACKEND_GUEST,
LB_BACKEND_HOST,
LB_BACKEND_IP,
)
const (

View File

@@ -49,4 +49,9 @@ var (
NETWORK_TYPE_PXE,
NETWORK_TYPE_IPMI,
}
REGINAL_NETWORK_PROVIDERS = []string{
CLOUD_PROVIDER_HUAWEI,
CLOUD_PROVIDER_UCLOUD,
}
)

View File

@@ -23,6 +23,7 @@ const (
STORAGE_NAS = "nas"
STORAGE_VSAN = "vsan"
STORAGE_NFS = "nfs"
STORAGE_GPFS = "gpfs"
STORAGE_PUBLIC_CLOUD = "cloud"
STORAGE_CLOUD_EFFICIENCY = "cloud_efficiency"
@@ -83,7 +84,7 @@ var (
STORAGE_ALL_TYPES = []string{
STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN,
STORAGE_NFS,
STORAGE_NFS, STORAGE_GPFS,
}
STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN, STORAGE_NFS,
@@ -94,7 +95,15 @@ var (
STORAGE_HUAWEI_SSD, STORAGE_HUAWEI_SAS, STORAGE_HUAWEI_SATA,
STORAGE_OPENSTACK_ISCSI, STORAGE_UCLOUD_CLOUD_NORMAL, STORAGE_UCLOUD_CLOUD_SSD,
STORAGE_UCLOUD_LOCAL_NORMAL, STORAGE_UCLOUD_LOCAL_SSD, STORAGE_UCLOUD_EXCLUSIVE_LOCAL_DISK,
STORAGE_GPFS,
}
STORAGE_LIMITED_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_NAS, STORAGE_RBD, STORAGE_NFS}
HOST_STORAGE_LOCAL_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL}
STORAGE_LIMITED_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_NAS, STORAGE_RBD, STORAGE_NFS, STORAGE_GPFS}
SHARED_FILE_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS}
// 目前来说只支持这些
SHARED_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS, STORAGE_RBD}
)

1
pkg/apis/image/doc.go Normal file
View File

@@ -0,0 +1 @@
package image // import "yunion.io/x/onecloud/pkg/apis/image"

View File

@@ -52,9 +52,6 @@ type ServerConfig struct {
Name string `json:"name"`
GuestStatus string `json:"guest_status"`
// HostId used by migrate
HostId string `json:"host_id"`
// DEPRECATED
Metadata map[string]string `json:"__meta__"`
ForGuests []*ForGuest `json:"for_guests"`
@@ -70,6 +67,12 @@ type ScheduleInput struct {
ScheduleBaseConfig
ServerConfig
// HostId used by migrate
HostId string `json:"host_id"`
LiveMigrate bool `json:"live_migrate"`
CpuDesc string `json:"cpu_desc"`
CpuMicrocode string `json:"cpu_microcode"`
}
func (input ScheduleInput) ToConditionInput() *jsonutils.JSONDict {
@@ -90,10 +93,11 @@ type CandidateNet struct {
}
type CandidateResource struct {
HostId string `json:"host_id"`
Name string `json:"name"`
Disks []*CandidateDisk `json:"disks"`
Nets []*CandidateNet `json:"nets"`
SessionId string `json:"session_id"`
HostId string `json:"host_id"`
Name string `json:"name"`
Disks []*CandidateDisk `json:"disks"`
Nets []*CandidateNet `json:"nets"`
// used by backup schedule
BackupCandidate *CandidateResource `json:"backup_candidate"`

View File

@@ -245,7 +245,7 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
if ok {
fw := newResponseWriterChannel(w)
worker := make(chan *SWorker)
to := hand.processTimeout
to := hand.FetchProcessTimeout(r)
if to == 0 {
to = app.processTimeout
}

View File

@@ -41,6 +41,14 @@ type SHandlerInfo struct {
skipLog bool
}
func (this *SHandlerInfo) FetchProcessTimeout(r *http.Request) time.Duration {
if r.Method == http.MethodGet && len(r.URL.Query().Get("export_keys")) > 0 {
return time.Hour * 2
} else {
return this.processTimeout
}
}
func (this *SHandlerInfo) GetName(params map[string]string) string {
if len(this.name) > 0 {
return this.name

View File

@@ -25,9 +25,11 @@ import (
"sync"
"time"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/errors"
yerrors "yunion.io/x/pkg/util/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/seclib"
"yunion.io/x/pkg/util/sets"
@@ -120,7 +122,7 @@ func (m *SBaremetalManager) loadConfigs() error {
errs = append(errs, <-errsChannel)
}
}
return errors.NewAggregate(errs)
return yerrors.NewAggregate(errs)
}
func (m *SBaremetalManager) initBaremetal(session *mcclient.ClientSession, bmId string) error {
@@ -191,7 +193,7 @@ func (m *SBaremetalManager) GetBaremetalById(bmId string) *SBaremetalInstance {
}
func (m *SBaremetalManager) GetBaremetalByMac(mac net.HardwareAddr) pxe.IBaremetalInstance {
var obj *SBaremetalInstance
var obj pxe.IBaremetalInstance
getter := func(key, val interface{}) bool {
instance := val.(*SBaremetalInstance)
if instance.GetNicByMac(mac) != nil {
@@ -282,7 +284,7 @@ func (b *SBaremetalInstance) GetClientSession() *mcclient.ClientSession {
func (b *SBaremetalInstance) GetId() string {
id, err := b.desc.GetString("id")
if err != nil {
log.Fatalf("Get id from desc error: %v", err)
log.Errorf("Get id from desc %s error: %v", b.desc.String(), err)
}
return id
}
@@ -290,7 +292,7 @@ func (b *SBaremetalInstance) GetId() string {
func (b *SBaremetalInstance) GetName() string {
id, err := b.desc.GetString("name")
if err != nil {
log.Fatalf("Get name from desc error: %v", err)
log.Fatalf("Get name from desc %s error: %v", b.desc.String(), err)
}
return id
}
@@ -690,24 +692,41 @@ func (b *SBaremetalInstance) GetNotifyUrl() string {
return fmt.Sprintf("%s/baremetals/%s/notify", b.manager.Agent.GetManagerUri(), b.GetId())
}
func (b *SBaremetalInstance) getTftpFileUrl(filename string) string {
serverIP, err := b.manager.Agent.GetDHCPServerIP()
if err != nil {
log.Errorf("Get http file server: %v", err)
return filename
}
if o.Options.EnableTftpHttpDownload {
return fmt.Sprintf("http://%s:%d/tftp/%s", serverIP, o.Options.Port+1000, filename)
}
return filename
}
func (b *SBaremetalInstance) GetTFTPResponse() string {
resp := `default start
resp := `DEFAULT start
serial 1 115200
label start
menu label ^Start
menu default
LABEL start
MENU LABEL ^Start
MENU default
`
if b.NeedPXEBoot() {
resp += " kernel kernel\n"
resp += fmt.Sprintf(" append initrd=initramfs token=%s url=%s",
auth.GetTokenString(), b.GetNotifyUrl())
resp += fmt.Sprintf(" kernel %s\n", b.getTftpFileUrl("kernel"))
args := []string{
fmt.Sprintf("initrd=%s", b.getTftpFileUrl("initramfs")),
fmt.Sprintf("token=%s", auth.GetTokenString()),
fmt.Sprintf("url=%s", b.GetNotifyUrl()),
}
resp += fmt.Sprintf(" append %s\n", strings.Join(args, " "))
} else {
resp += " COM32 chain.c32\n"
resp += fmt.Sprintf(" COM32 %s\n", b.getTftpFileUrl("chain.c32"))
resp += " APPEND hd0 0\n"
b.ClearSSHConfig()
}
log.Infof("%s", resp)
log.Infof("[TFTP response]: \n%s", resp)
return resp
}
@@ -999,6 +1018,7 @@ func (b *SBaremetalInstance) StartNewTask(factory tasks.TaskFactory, taskId stri
go func() {
task, err := factory(b, taskId, data)
if err != nil {
log.Errorf("New task %#v error: %v", factory, err)
tasks.SetTaskFail(task, err)
return
}
@@ -1165,7 +1185,7 @@ func (server *SBaremetalServer) GetId() string {
func (server *SBaremetalServer) GetName() string {
id, err := server.desc.GetString("name")
if err != nil {
log.Fatalf("Get name from desc error: %v", err)
log.Errorf("Get name from desc %s error: %v", server.desc.String(), err)
}
return id
}
@@ -1311,40 +1331,40 @@ func (s *SBaremetalServer) DoPartitionDisk(term *ssh.Client) ([]*disktool.Partit
storages = append(storages, pcie...)
confs, err := s.GetDiskConfig()
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "do disk config")
}
layouts, err := baremetal.CalculateLayout(confs, storages)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "CalculateLayout")
}
tool := disktool.NewSSHPartitionTool(term)
tool.FetchDiskConfs(baremetal.GetDiskConfigurations(layouts))
err = tool.RetrieveDiskInfo()
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "RetrieveDiskInfo")
}
disks, _ := s.desc.GetArray("disks")
if len(disks) == 0 {
return nil, fmt.Errorf("Empty disks in desc")
return nil, errors.New("Empty disks in desc")
}
rootDisk := disks[0]
rootSize, _ := rootDisk.Int("size")
err = s.doCreateRoot(term, tool.GetRootDisk().GetDevName())
if err != nil {
return nil, fmt.Errorf("Failed to create root: %v", err)
return nil, errors.Wrapf(err, "Failed to create root")
}
tool.RetrievePartitionInfo()
parts := tool.GetPartitions()
if len(parts) == 0 {
return nil, fmt.Errorf("Root disk create failed, no partitions")
return nil, errors.New("Root disk create failed, no partitions")
}
log.Infof("Resize root to %d MB", rootSize)
if err := tool.ResizePartition(0, rootSize); err != nil {
return nil, fmt.Errorf("Fail to resize root to %d, err: %v", rootSize, err)
return nil, errors.Wrapf(err, "Fail to resize root to %d", rootSize)
}
if len(disks) > 1 {
for _, disk := range disks[1:] {
@@ -1357,7 +1377,7 @@ func (s *SBaremetalServer) DoPartitionDisk(term *ssh.Client) ([]*disktool.Partit
driver, _ := disk.GetString("driver")
log.Infof("Create partition %d %s", sz, fs)
if err := tool.CreatePartition(-1, sz, fs, true, driver, uuid); err != nil {
return nil, fmt.Errorf("Fail to create disk %s: %v", disk.String(), err)
return nil, errors.Wrapf(err, "Fail to create disk %s", disk.String())
}
}
}
@@ -1398,15 +1418,18 @@ func (s *SBaremetalServer) DoRebuildRootDisk(term *ssh.Client) ([]*disktool.Part
rootDisk := disks[0]
rootSize, _ := rootDisk.Int("size")
err = s.doCreateRoot(term, tool.GetRootDisk().GetDevName())
rd := tool.GetRootDisk()
err = s.doCreateRoot(term, rd.GetDevName())
if err != nil {
return nil, fmt.Errorf("Failed to create root: %v", err)
}
tool.RetrievePartitionInfo()
if err := rd.ReInitInfo(); err != nil {
return nil, errors.Wrap(err, "Reinit root disk after create root")
}
log.Infof("Resize root to %d MB", rootSize)
if err := tool.ResizePartition(0, rootSize); err != nil {
if err := rd.ResizePartition(rootSize); err != nil {
return nil, fmt.Errorf("Fail to resize root to %d, err: %v", rootSize, err)
}
if len(disks) > 1 {
@@ -1417,17 +1440,24 @@ func (s *SBaremetalServer) DoRebuildRootDisk(term *ssh.Client) ([]*disktool.Part
}
fs, _ := disk.GetString("fs")
uuid, _ := disk.GetString("disk_id")
driver, _ := disk.GetString("driver")
log.Infof("Create partition %d %s", sz, fs)
if err := tool.CreatePartition(0, sz, fs, false, driver, uuid); err != nil {
log.Errorf("Rebuild root create (%s, %d, %s, %s) partition error: %v", uuid, sz, fs, driver, err)
if err := rd.CreatePartition(sz, fs, false, uuid); err != nil {
log.Errorf("Rebuild root create (%s, %d, %s) partition error: %v", uuid, sz, fs, err)
break
}
}
}
log.Infof("Finish create partitions")
return tool.GetPartitions(), nil
parts := rd.GetPartitions()
restDisks := tool.Disks()
if len(restDisks) > 1 {
restDisks = restDisks[1:]
}
for _, d := range restDisks {
parts = append(parts, d.GetPartitions()...)
}
return parts, nil
}
func (s *SBaremetalServer) SyncPartitionSize(term *ssh.Client, parts []*disktool.Partition) ([]jsonutils.JSONObject, error) {

View File

@@ -76,7 +76,11 @@ func GetNicDHCPConfig(
case 6:
conf.BootFile = "bootia32.efi"
default:
conf.BootFile = "pxelinux.0"
bootFile := "pxelinux.0"
if o.Options.EnableTftpHttpDownload {
bootFile = "lpxelinux.0"
}
conf.BootFile = bootFile
}
pxePath := filepath.Join(o.Options.TftpRoot, conf.BootFile)
if f, err := os.Open(pxePath); err != nil {

View File

@@ -22,7 +22,7 @@ type BaremetalOptions struct {
ListenInterface string `help:"Master net interface of baremetal server" default:"br0"`
AccessAddress string `help:"Management IP address of baremetal server, only need to use when multiple address bind to ListenInterface"`
ListenAddress string `help:"PXE serve IP address to select when multiple address bind to ListenInterface" default:"0.0.0.0"`
TftpRoot string `help:"tftp root directory"`
TftpRoot string `default:"/opt/cloud/yunion/baremetal" help:"tftp root directory"`
AutoRegisterBaremetal bool `default:"true" help:"Automatically create a baremetal instance"`
BaremetalsPath string `default:"/opt/cloud/workspace/baremetals" help:"Path for baremetals configuration files"`
LinuxDefaultRootUser bool `default:"false" help:"Default account for linux system is root"`
@@ -41,6 +41,7 @@ type BaremetalOptions struct {
DefaultStrongIpmiPassword string `help:"Default strong IPMI passowrd"`
WindowsDefaultAdminUser bool `default:"true" help:"Default account for Windows system is Administrator"`
EnableTftpHttpDownload bool `default:"true" help:"Pxelinux download file through http"`
}
var (

View File

@@ -15,6 +15,8 @@
package service
import (
"fmt"
"net/http"
"os"
"yunion.io/x/log"
@@ -43,12 +45,27 @@ func (s *BaremetalService) StartService() {
app := app_common.InitApp(&o.Options.CommonOptions, false)
handler.InitHandlers(app)
s.startFileServer()
app_common.ServeForeverWithCleanup(app, &o.Options.CommonOptions, func() {
tasks.OnStop()
baremetal.Stop()
})
}
func (s *BaremetalService) startFileServer() {
if !o.Options.EnableTftpHttpDownload {
return
}
fs := http.FileServer(http.Dir(o.Options.TftpRoot))
http.Handle("/tftp/", http.StripPrefix("/tftp/", fs))
go func() {
if err := http.ListenAndServe(fmt.Sprintf("%s:%d", o.Options.Address, o.Options.Port+1000), nil); err != nil {
panic(fmt.Sprintf("start http file server: %v", err))
}
}()
}
func (s *BaremetalService) startAgent() {
err := baremetal.Start()
if err != nil {

View File

@@ -21,6 +21,8 @@ import (
"sync"
"time"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -287,18 +289,18 @@ func (self *SBaremetalTaskBase) EnsurePowerUp() error {
log.Infof("EnsurePowerUp: bootdev=pxe")
status, err := self.Baremetal.GetPowerStatus()
if err != nil {
return err
return errors.Wrapf(err, "Get power status")
}
for status == "" || status == types.POWER_STATUS_OFF {
if status == types.POWER_STATUS_OFF {
err = self.Baremetal.DoPXEBoot()
if err != nil {
return err
return errors.Wrapf(err, "Do PXE boot")
}
}
status, err = self.Baremetal.GetPowerStatus()
if err != nil {
return err
return errors.Wrapf(err, "Get power status")
}
if status == "" || status == types.POWER_STATUS_OFF {
time.Sleep(40 * time.Second)
@@ -367,7 +369,7 @@ func (self *SBaremetalPXEBootTaskBase) InitPXEBootTask(pxeBootTask IPXEBootTask,
return self, fmt.Errorf("EnsurePowerShutdown: %v", err)
}
if err := self.EnsurePowerUp(); err != nil {
return self, fmt.Errorf("EnsurePowerUp to pxe: %v", err)
return self, errors.Wrapf(err, "EnsurePowerUp to pxe")
}
// this stage will be called by baremetalInstance when pxe start notify
self.SetSSHStage(pxeBootTask.OnPXEBoot)

View File

@@ -17,6 +17,8 @@ package tasks
import (
"context"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
@@ -64,25 +66,25 @@ func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term
log.Infof("%s called on stage pxeboot, args: %v", self.GetName(), args)
result, err := self.serverDeployTask.DoDeploys(term)
if err != nil {
return err
return errors.Wrap(err, "Do deploy")
}
_, err = term.Run(
"/bin/sync",
"/sbin/sysctl -w vm.drop_caches=3",
)
if err != nil {
return err
return errors.Wrap(err, "Sync disk")
}
onFinishAction := self.GetFinishAction()
if utils.IsInStringArray(onFinishAction, []string{"restart", "shutdown"}) {
err = self.EnsurePowerShutdown(false)
if err != nil {
return err
return errors.Wrap(err, "Ensure power off")
}
if onFinishAction == "restart" {
err = self.EnsurePowerUp()
if err != nil {
return err
return errors.Wrap(err, "Ensure power up")
}
}
}

View File

@@ -205,7 +205,7 @@ func (task *sBaremetalPrepareTask) DoPrepare(cli *ssh.Client) error {
if lanConf.IPAddr == nic.IpAddr {
break
}
log.Infof("waiting IPMI DHCP address %s %s", lanConf.IPAddr, nic.IpAddr)
log.Infof("waiting IPMI DHCP address old:%s expect:%s", lanConf.IPAddr, nic.IpAddr)
tried += 2
}
if tried >= maxTries {
@@ -262,14 +262,15 @@ func (task *sBaremetalPrepareTask) DoPrepare(cli *ssh.Client) error {
if err := task.sendStorageInfo(size); err != nil {
log.Errorf("sendStorageInfo error: %v", err)
}
for i := range nicsInfo {
if nicsInfo[i].Mac.String() == adminNic.GetMac().String() {
if i != 0 {
nicsInfo = append(nicsInfo[i:], nicsInfo[0:i]...)
}
break
}
}
// XXX do not change nic order anymore
// for i := range nicsInfo {
// if nicsInfo[i].Mac.String() == adminNic.GetMac().String() {
// if i != 0 {
// nicsInfo = append(nicsInfo[i:], nicsInfo[0:i]...)
// }
// break
// }
// }
err = task.removeAllNics()
if err != nil {
return err

View File

@@ -74,6 +74,7 @@ func (self *SBaremetalServerCreateTask) DoDeploys(term *ssh.Client) (jsonutils.J
}
func (self *SBaremetalServerCreateTask) onError(term *ssh.Client, err error) error {
log.Errorf("Create server error: %+v", err)
if err1 := self.Baremetal.GetServer().DoEraseDisk(term); err1 != nil {
log.Warningf("EraseDisk error: %v", err1)
}

View File

@@ -36,8 +36,8 @@ func GetRaidDevices(drv raid.IRaidDriver) []*baremetal.BaremetalStorage {
return devs
}
func GetRaidLogicVolumes(drv raid.IRaidDriver) ([]int, error) {
lvs := []int{}
func GetRaidLogicVolumes(drv raid.IRaidDriver) ([]*raid.RaidLogicalVolume, error) {
lvs := []*raid.RaidLogicalVolume{}
for _, adapter := range drv.GetAdapters() {
lv, err := adapter.GetLogicVolumes()
if err != nil {
@@ -50,12 +50,12 @@ func GetRaidLogicVolumes(drv raid.IRaidDriver) ([]int, error) {
func DetectStorageInfo(term *ssh.Client, wait bool) ([]*baremetal.BaremetalStorage, []*baremetal.BaremetalStorage, []*baremetal.BaremetalStorage, error) {
raidDiskInfo := make([]*baremetal.BaremetalStorage, 0)
lvDiskInfo := make([]int, 0)
lvDiskInfo := make([]*raid.RaidLogicalVolume, 0)
raidDrivers := []string{}
for _, drv := range drivers.GetDrivers(term) {
if err := drv.ParsePhyDevs(); err != nil {
log.V(2).Warningf("ParsePhyDevs: %v", err)
log.Warningf("Raid driver %s ParsePhyDevs: %v", drv.GetName(), err)
continue
}
raidDiskInfo = append(raidDiskInfo, GetRaidDevices(drv)...)
@@ -70,8 +70,7 @@ func DetectStorageInfo(term *ssh.Client, wait bool) ([]*baremetal.BaremetalStora
raidDrivers = append(raidDrivers, drv.GetName())
}
log.Infof("Get Raid drivers: %v", raidDrivers)
log.Infof("Get Raid drivers: %v, collecting disks info ...", raidDrivers)
pcieRet, err := term.Run("/lib/mos/lsdisk --pcie")
if err != nil {
return nil, nil, nil, fmt.Errorf("Fail to retrieve PCIE DISK info")

View File

@@ -19,8 +19,11 @@ import (
"math"
"strings"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
raiddrivers "yunion.io/x/onecloud/pkg/baremetal/utils/raid/drivers"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/compute/baremetal"
fileutils "yunion.io/x/onecloud/pkg/util/fileutils2"
@@ -205,6 +208,7 @@ func (p *Partition) GetSizeMB() (int64, error) {
type DiskPartitions struct {
driver string
adapter int
raidConfig string
sizeMB int64 // MB
tool *PartitionTool
dev string
@@ -217,10 +221,11 @@ type DiskPartitions struct {
partitions []*Partition
}
func newDiskPartitions(driver string, adapter int, sizeMB int64, blockSize int64, tool *PartitionTool) *DiskPartitions {
func newDiskPartitions(driver string, adapter int, raidConfig string, sizeMB int64, blockSize int64, tool *PartitionTool) *DiskPartitions {
ps := new(DiskPartitions)
ps.driver = driver
ps.adapter = adapter
ps.raidConfig = raidConfig
ps.sizeMB = sizeMB
ps.tool = tool
ps.blockSize = blockSize
@@ -228,6 +233,15 @@ func newDiskPartitions(driver string, adapter int, sizeMB int64, blockSize int64
return ps
}
func (p *DiskPartitions) IsRaidDriver() bool {
return utils.IsInStringArray(p.driver, []string{
baremetal.DISK_DRIVER_MEGARAID,
baremetal.DISK_DRIVER_HPSARAID,
baremetal.DISK_DRIVER_MARVELRAID,
baremetal.DISK_DRIVER_MPT2SAS,
})
}
func (p *DiskPartitions) SetInfo(info *types.SDiskInfo) *DiskPartitions {
p.dev = fmt.Sprintf("/dev/%s", info.Dev)
p.devName = info.Dev
@@ -240,6 +254,20 @@ func (p *DiskPartitions) SetInfo(info *types.SDiskInfo) *DiskPartitions {
return p
}
func (p *DiskPartitions) ReInitInfo() error {
cmd := "/lib/mos/lsdisk"
lines, err := p.tool.Run(cmd)
if err != nil {
return errors.Wrapf(err, "Disk %#v reset info list disk", p)
}
for _, disk := range sysutils.ParseDiskInfo(lines, p.driver) {
if disk.Dev == p.GetDevName() {
p.SetInfo(disk)
}
}
return p.RetrievePartitionInfo()
}
func (ps *DiskPartitions) MBSectors() int64 {
return int64(1024 * 1024 / ps.blockSize)
}
@@ -264,7 +292,27 @@ func (ps *DiskPartitions) IsReady() bool {
}
func (ps *DiskPartitions) GetDevName() string {
return ps.devName
devName := ps.devName
if !ps.IsRaidDriver() || ps.raidConfig == baremetal.DISK_CONF_NONE {
return devName
}
raidDrv, err := raiddrivers.GetDriverWithInit(ps.driver, ps.tool.runner.Term())
if err != nil {
log.Errorf("Failed to find %s raid driver: %v", ps.driver, err)
return devName
}
// find first raid adapter logical volume
lv, err := raiddrivers.GetFirstLogicalVolume(raidDrv, ps.adapter)
if err != nil {
log.Errorf("Failed to find raid %s adapter %d first logical volume: %v", raidDrv.GetName(), ps.adapter, err)
return devName
}
if len(lv.BlockDev) == 0 {
log.Warningf("Raid %s adapter %d first logical volume block device is empty", raidDrv.GetName(), ps.adapter)
return devName
}
devName = strings.TrimLeft(lv.BlockDev, "/dev/")
return devName
}
func (ps *DiskPartitions) RetrievePartitionInfo() error {
@@ -312,6 +360,10 @@ func (ps *DiskPartitions) doResize(dev string, cmd string) error {
return ps.RetrievePartitionInfo()
}
func (ps *DiskPartitions) GetPartitions() []*Partition {
return ps.partitions
}
func (ps *DiskPartitions) ResizePartition(offsetMB int64) error {
if len(ps.partitions) == 0 {
return fmt.Errorf("ResizePartitions error: total %d partitions", len(ps.partitions))
@@ -512,6 +564,7 @@ func (ps *DiskPartitions) CreatePartition(sizeMB int64, fs string, doformat bool
type IPartitionRunner interface {
Run(cmds ...string) ([]string, error)
Term() *ssh.Client
}
type PartitionTool struct {
@@ -543,6 +596,10 @@ func (tool *PartitionTool) DebugString() string {
return strings.Join(ret, "\n")
}
func (tool *PartitionTool) Disks() []*DiskPartitions {
return tool.disks
}
func (tool *PartitionTool) parseLsDisk(lines []string, driver string) {
disks := sysutils.ParseDiskInfo(lines, driver)
if len(disks) == 0 {
@@ -556,7 +613,7 @@ func (tool *PartitionTool) parseLsDisk(lines []string, driver string) {
func (tool *PartitionTool) FetchDiskConfs(diskConfs []baremetal.DiskConfiguration) *PartitionTool {
for _, d := range diskConfs {
disk := newDiskPartitions(d.Driver, d.Adapter, d.Size, d.Block, tool)
disk := newDiskPartitions(d.Driver, d.Adapter, d.RaidConfig, d.Size, d.Block, tool)
tool.disks = append(tool.disks, disk)
var key string
if d.Driver == baremetal.DISK_DRIVER_LINUX {
@@ -575,9 +632,9 @@ func (tool *PartitionTool) FetchDiskConfs(diskConfs []baremetal.DiskConfiguratio
}
func (tool *PartitionTool) IsAllDisksReady() bool {
for _, d := range tool.disks {
for idx, d := range tool.disks {
if !d.IsReady() {
log.Errorf("disk %#v not ready", d)
log.Errorf("disk.%d %#v not ready", idx, d)
return false
}
}
@@ -681,3 +738,7 @@ func NewSSHPartitionTool(term *ssh.Client) *SSHPartitionTool {
func (tool *SSHPartitionTool) Run(cmds ...string) ([]string, error) {
return tool.term.Run(cmds...)
}
func (tool *SSHPartitionTool) Term() *ssh.Client {
return tool.term
}

View File

@@ -21,6 +21,8 @@ import (
"strings"
"time"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/stringutils"
@@ -444,7 +446,7 @@ func DoReboot(exector IPMIExecutor) error {
var err error
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
log.Errorf("DoReboot get power status 1st: %v", err)
}
isValidStatus := func(s string) bool {
@@ -455,25 +457,24 @@ func DoReboot(exector IPMIExecutor) error {
time.Sleep(1 * time.Second)
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
log.Errorf("DoReboot %d tries to get power status: %v", tried, err)
}
}
if !isValidStatus(status) {
return fmt.Errorf("Unexpected status: %s", status)
return fmt.Errorf("Unexpected power status: %q", status)
}
// do shutdown
if status == types.POWER_STATUS_ON {
err = DoHardShutdown(exector)
if err != nil {
return err
if err := DoHardShutdown(exector); err != nil {
log.Errorf("DoHardShutdown: %v", err)
}
time.Sleep(1 * time.Second)
for tried := 0; tried < maxTries; tried++ {
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
log.Errorf("DoReboot %d tries to get power status: %v", tried, err)
}
if status == types.POWER_STATUS_OFF {
break
@@ -483,28 +484,24 @@ func DoReboot(exector IPMIExecutor) error {
}
// do power on
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
}
status, _ = GetChassisPowerStatus(exector)
for tried := 0; status != types.POWER_STATUS_ON && tried < maxTries; tried++ {
err = DoPowerOn(exector)
if err != nil {
return err
if err := DoPowerOn(exector); err != nil {
log.Errorf("DoReboot %d tries to power on: %v", tried, err)
}
time.Sleep(1 * time.Second)
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
log.Errorf("DoReboot %d tries to get power status: %v", tried, err)
}
}
status, err = GetChassisPowerStatus(exector)
if err != nil {
return err
return errors.Wrap(err, "Get power status after power on")
}
if status != types.POWER_STATUS_ON {
return fmt.Errorf("do reboot fail to poweron, current status: %s", status)
return errors.Errorf("do reboot fail to poweron, current status: %s", status)
}
return nil
}

View File

@@ -17,6 +17,10 @@ package drivers
import (
"fmt"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/hpssactl"
@@ -35,6 +39,30 @@ func GetDriver(name string, term *ssh.Client) raid.IRaidDriver {
return factory(term)
}
func GetDriverWithInit(name string, term *ssh.Client) (raid.IRaidDriver, error) {
drv := GetDriver(name, term)
if drv == nil {
return nil, errors.Errorf("Not found raid driver %q", name)
}
return drv, drv.ParsePhyDevs()
}
func GetDriverByKernelModule(module string, term *ssh.Client) (raid.IRaidDriver, error) {
name := ""
switch module {
case raid.MODULE_MEGARAID:
name = baremetal.DISK_DRIVER_MEGARAID
case raid.MODULE_HPSA:
name = baremetal.DISK_DRIVER_HPSARAID
case raid.MODULE_MPT2SAS, raid.MODULE_MPT3SAS:
name = baremetal.DISK_DRIVER_MPT2SAS
}
if name == "" {
return nil, errors.Errorf("Not support module %q", module)
}
return GetDriverWithInit(name, term)
}
func GetDrivers(term *ssh.Client) []raid.IRaidDriver {
ret := []raid.IRaidDriver{}
for _, factory := range raid.RaidDrivers {
@@ -111,3 +139,41 @@ func buildRaid(adapter raid.IRaidAdapter, confs []*api.BaremetalDiskConfig) erro
}
return nil
}
func GetFirstLogicalVolume(drv raid.IRaidDriver, adapterIdx int) (*raid.RaidLogicalVolume, error) {
var adapter raid.IRaidAdapter = nil
for _, ada := range drv.GetAdapters() {
if ada.GetIndex() == adapterIdx {
adapter = ada
}
}
if adapter == nil {
return nil, errors.Errorf("Not found raid %s adapter %d", drv.GetName(), adapterIdx)
}
lvs, err := adapter.GetLogicVolumes()
if err != nil {
return nil, errors.Wrapf(err, "Get adapter logical volume")
}
if len(lvs) == 0 {
return nil, errors.Errorf("Adapter %d empty logical volume", adapterIdx)
}
return lvs[0], nil
}
func GetBlockDeviceLogicalVolume(drv raid.IRaidDriver, blockDev string) (*raid.RaidLogicalVolume, error) {
lvs := make([]*raid.RaidLogicalVolume, 0)
for _, ada := range drv.GetAdapters() {
aLvs, err := ada.GetLogicVolumes()
if err != nil {
return nil, errors.Errorf("Get adapter %d logical volumes: %v", ada.GetIndex(), err)
}
lvs = append(lvs, aLvs...)
}
log.Debugf("Get logic volumes: %s", jsonutils.Marshal(lvs).String())
for _, lv := range lvs {
if lv.BlockDev == blockDev {
return lv, nil
}
}
return nil, errors.Errorf("Not found logical volume by block device %s", blockDev)
}

View File

@@ -20,7 +20,10 @@ import (
"strconv"
"strings"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/pkg/utils"
@@ -39,14 +42,19 @@ type HPSARaidPhyDev struct {
func newHPSARaidPhyDev(addr string, adapter int, rotate bool) *HPSARaidPhyDev {
b := raid.NewRaidBasePhyDev(baremetal.DISK_DRIVER_HPSARAID)
b.Adapter = adapter
if rotate {
b.Rotate = tristate.True
} else {
b.Rotate = tristate.False
}
return &HPSARaidPhyDev{
RaidBasePhyDev: b,
addr: addr,
}
}
func (dev *HPSARaidPhyDev) ToBaremetalStorage() *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage()
func (dev *HPSARaidPhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage(index)
s.Addr = dev.addr
return s
@@ -133,16 +141,20 @@ func (adapter *HPSARaidAdaptor) ParsePhyDevs() error {
adapter.parsePhyDevs(ret, isRotate)
return nil
}
cmd1 := GetCommand("controller", "slot=%d", fmt.Sprintf("%d", adapter.index), "ssdphysicaldrive", "all", "show", "detail")
cmd2 := GetCommand("controller", "slot=%d", fmt.Sprintf("%d", adapter.index), "physicaldrive", "all", "show", "detail")
var err error
if err = parseByCmd(cmd1, false); err != nil {
log.Errorf("parsePhyDevs by cmd %q: %v", cmd1, err)
cmd1 := GetCommand("controller", fmt.Sprintf("slot=%d", adapter.index), "ssdphysicaldrive", "all", "show", "detail")
cmd2 := GetCommand("controller", fmt.Sprintf("slot=%d", adapter.index), "physicaldrive", "all", "show", "detail")
var err1 error
var err2 error
if err1 = parseByCmd(cmd1, false); err1 != nil {
err1 = errors.Errorf("parsePhyDevs by cmd %q: %v", cmd1, err1)
}
if err = parseByCmd(cmd2, true); err != nil {
log.Errorf("parsePhyDevs by cmd %q: %v", cmd1, err)
if err2 = parseByCmd(cmd2, true); err2 != nil {
err2 = errors.Errorf("parsePhyDevs by cmd %q: %v", cmd1, err2)
}
return err
if err1 != nil && err2 != nil {
return errors.Errorf("ssd: %v, hdd: %v", err1, err2)
}
return nil
}
func (adapter *HPSARaidAdaptor) parsePhyDevs(lines []string, isRotate bool) {
@@ -153,7 +165,7 @@ func (adapter *HPSARaidAdaptor) parsePhyDevs(lines []string, isRotate bool) {
phydev = newHPSARaidPhyDev(m["addr"], adapter.index, isRotate)
} else if phydev != nil && phydev.parseLine(line) && phydev.isComplete() {
oldDev := adapter.getPhyDevByAddr(phydev.addr)
if oldDev != nil {
if oldDev == nil {
adapter.devs = append(adapter.devs, phydev)
}
phydev = nil
@@ -172,8 +184,8 @@ func (adapter *HPSARaidAdaptor) getPhyDevByAddr(addr string) *HPSARaidPhyDev {
func (adapter *HPSARaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
ret := []*baremetal.BaremetalStorage{}
for _, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage())
for idx, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage(idx))
}
return ret
}
@@ -263,7 +275,7 @@ func (adapter *HPSARaidAdaptor) BuildRaid5(devs []*baremetal.BaremetalStorage, c
}
func (adapter *HPSARaidAdaptor) BuildRaid10(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
return adapter.buildRaid("10", devs, conf)
return adapter.buildRaid("1+0", devs, conf)
}
func (adapter *HPSARaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage) error {
@@ -285,7 +297,7 @@ func (adapter *HPSARaidAdaptor) removeLogicVolume(idx int) error {
return err
}
func (adapter *HPSARaidAdaptor) GetLogicVolumes() ([]int, error) {
func (adapter *HPSARaidAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) {
cmd := GetCommand("controller", fmt.Sprintf("slot=%d", adapter.index), "logicaldrive", "all", "show")
ret, err := adapter.raid.term.Run(cmd)
if err != nil {
@@ -294,8 +306,8 @@ func (adapter *HPSARaidAdaptor) GetLogicVolumes() ([]int, error) {
return adapter.parseLogicalVolumes(ret)
}
func (adapter *HPSARaidAdaptor) parseLogicalVolumes(lines []string) ([]int, error) {
lvs := []int{}
func (adapter *HPSARaidAdaptor) parseLogicalVolumes(lines []string) ([]*raid.RaidLogicalVolume, error) {
lvs := []*raid.RaidLogicalVolume{}
for _, line := range lines {
m := regutils2.SubGroupMatch(`logicaldrive\s+(?P<addr>\w+)`, line)
if len(m) > 0 {
@@ -304,7 +316,10 @@ func (adapter *HPSARaidAdaptor) parseLogicalVolumes(lines []string) ([]int, erro
if err != nil {
return nil, fmt.Errorf("%s not int: %v", idxStr, err)
}
lvs = append(lvs, idx)
lvs = append(lvs, &raid.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
})
}
}
return lvs, nil
@@ -315,9 +330,9 @@ func (adapter *HPSARaidAdaptor) RemoveLogicVolumes() error {
if err != nil {
return fmt.Errorf("Failed to get logic volumes: %v", err)
}
for i := len(lvs) - 1; i >= 0; i-- {
if err := adapter.removeLogicVolume(i); err != nil {
return fmt.Errorf("Remove %d logical volume: %v", i, err)
for _, i := range raid.ReverseLogicalArray(lvs) {
if err := adapter.removeLogicVolume(i.Index); err != nil {
return fmt.Errorf("Remove %#v logical volume: %v", i, err)
}
}
return nil
@@ -336,7 +351,7 @@ func NewHPSARaid(term *ssh.Client) raid.IRaidDriver {
}
func (r *HPSARaid) ParsePhyDevs() error {
if !utils.IsInStringArray("hpsa", raid.GetModules(r.term)) {
if !utils.IsInStringArray(raid.MODULE_HPSA, raid.GetModules(r.term)) {
return fmt.Errorf("Not found hpsa module")
}
cmd := GetCommand("controller", "all", "show")

View File

@@ -31,7 +31,7 @@ type IRaidDriver interface {
type IRaidAdapter interface {
GetIndex() int
PreBuildRaid(confs []*api.BaremetalDiskConfig) error
GetLogicVolumes() ([]int, error)
GetLogicVolumes() ([]*RaidLogicalVolume, error)
RemoveLogicVolumes() error
GetDevices() []*baremetal.BaremetalStorage

View File

@@ -20,6 +20,7 @@ import (
"strconv"
"strings"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/stringutils"
@@ -60,8 +61,8 @@ func NewMegaRaidPhyDev() *MegaRaidPhyDev {
}
}
func (dev *MegaRaidPhyDev) ToBaremetalStorage() *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage()
func (dev *MegaRaidPhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage(index)
s.Enclosure = dev.enclosure
s.Slot = dev.slot
s.Size = dev.GetSize()
@@ -182,16 +183,130 @@ func GetSpecString(dev *baremetal.BaremetalStorage) string {
}
type MegaRaidAdaptor struct {
index int
raid *MegaRaid
devs []*MegaRaidPhyDev
index int
storcliIndex int
raid *MegaRaid
devs []*MegaRaidPhyDev
sn string
busNumber string
deviceNumber string
funcNumber string
// used by sg_map
hostNum int
//channelNum int
}
func NewMegaRaidAdaptor(index int, raid *MegaRaid) *MegaRaidAdaptor {
return &MegaRaidAdaptor{
index: index,
raid: raid,
func NewMegaRaidAdaptor(index int, raid *MegaRaid) (*MegaRaidAdaptor, error) {
adapter := &MegaRaidAdaptor{
index: index,
storcliIndex: -1,
raid: raid,
}
if err := adapter.fillInfo(); err != nil {
return adapter, errors.Wrapf(err, "%d fill info", adapter.index)
}
return adapter, nil
}
func (adapter *MegaRaidAdaptor) fillInfo() error {
cmd := GetCommand("-AdpAllInfo", fmt.Sprintf("-a%d", adapter.index))
ret, err := adapter.remoteRun(cmd)
if err != nil {
return errors.Wrap(err, "remote get SN")
}
for _, l := range ret {
key, val := stringutils.SplitKeyValue(l)
if len(key) == 0 {
continue
}
switch key {
case "Serial No":
adapter.sn = val
}
}
if len(adapter.sn) == 0 {
return errors.New("Not found Serial No")
}
return adapter.fillPCIInfo()
}
func (adapter *MegaRaidAdaptor) fillPCIInfo() error {
cmd := GetCommand("-adpgetpciinfo", fmt.Sprintf("-a%d", adapter.index))
ret, err := adapter.remoteRun(cmd)
if err != nil {
return errors.Wrapf(err, "%d remote run get pci info", adapter.index)
}
for _, l := range ret {
key, val := stringutils.SplitKeyValue(l)
if len(key) == 0 {
continue
}
switch key {
case "Bus Number":
if len(val) == 1 {
val = fmt.Sprintf("0%s", val)
}
if len(val) != 2 {
return errors.Errorf("Invalid bus number: %s", val)
}
adapter.busNumber = val
case "Device Number":
if len(val) == 1 {
val = fmt.Sprintf("0%s", val)
}
if len(val) != 2 {
return errors.Errorf("Invalid device number: %s", val)
}
adapter.deviceNumber = val
case "Function Number":
if len(val) != 1 {
return errors.Errorf("Invalid function number: %s", val)
}
adapter.funcNumber = val
}
}
if len(adapter.busNumber) == 0 || len(adapter.deviceNumber) == 0 || len(adapter.funcNumber) == 0 {
return errors.New("Not found bus number")
}
pciDir := fmt.Sprintf("/sys/bus/pci/devices/0000:%s:%s.%s/", adapter.busNumber, adapter.deviceNumber, adapter.funcNumber)
cmd = raiddrivers.GetCommand("ls", pciDir, "|", "grep", "host")
ret, err = adapter.remoteRun(cmd)
if err != nil {
return errors.Wrapf(err, "find pci host number")
}
if len(ret) == 0 {
return errors.Errorf("Not find pci host dir")
}
hostNumStr := ret[0]
hostNum, err := strconv.Atoi(strings.TrimLeft(hostNumStr, "host"))
if err != nil {
return errors.Errorf("Invalid hostNum %s", hostNumStr)
}
adapter.hostNum = hostNum
pciHostDir := fmt.Sprintf("%s%s/", pciDir, hostNumStr)
// $ ls /sys/bus/pci/devices/0000:03:00.0/host0/ | grep target | head -n 1
// target0:2:0
targetCmd := raiddrivers.GetCommand("ls", pciHostDir, "|", "grep", "target", "|", "head", "-n", "1")
ret, err = adapter.remoteRun(targetCmd)
if err != nil {
return errors.Wrapf(err, "find target %q", targetCmd)
}
if len(ret) == 0 {
return errors.Errorf("Not find target dir")
}
//targetStr := ret[0]
//parts := strings.Split(targetStr, ":")
//if len(parts) != 3 {
//// not build raid logical volume yet
//log.Warningf("Cmd %q invalid target string %q, skip fill logical volume info", targetCmd, targetStr)
//return nil
//}
//channelNum, err := strconv.Atoi(parts[1])
//if err != nil {
//return errors.Errorf("Invalid channel number %s", parts[1])
//}
//adapter.channelNum = channelNum
return nil
}
func (adapter *MegaRaidAdaptor) GetIndex() int {
@@ -213,31 +328,61 @@ func (adapter *MegaRaidAdaptor) AddPhyDev(dev *MegaRaidPhyDev) {
func (adapter *MegaRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
ret := []*baremetal.BaremetalStorage{}
for _, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage())
for idx, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage(idx))
}
return ret
}
func (adapter *MegaRaidAdaptor) GetLogicVolumes() ([]int, error) {
func (adapter *MegaRaidAdaptor) GetLogicVolumes() ([]*raiddrivers.RaidLogicalVolume, error) {
cmd := GetCommand("-LDInfo", "-Lall", fmt.Sprintf("-a%d", adapter.index))
ret, err := adapter.remoteRun(cmd)
if err != nil {
return nil, fmt.Errorf("GetLogicVolumes error: %v", err)
}
return adapter.parseLogicVolumes(ret), nil
return adapter.parseLogicVolumes(ret)
}
func (adapter *MegaRaidAdaptor) parseLogicVolumes(lines []string) []int {
lvIdx := []int{}
var logicalVolumeIdRegexp = regexp.MustCompile(`.*(Target Id: (?P<idx>[0-9]+))`)
func (adapter *MegaRaidAdaptor) parseLogicVolumes(lines []string) ([]*raiddrivers.RaidLogicalVolume, error) {
lvs := make([]*raiddrivers.RaidLogicalVolume, 0)
for _, line := range lines {
key, val := stringutils.SplitKeyValue(line)
if key != "" && key == "Virtual Drive" {
idx, _ := strconv.Atoi(strings.Split(val, " ")[0])
lvIdx = append(lvIdx, idx)
idxStr := regutils2.GetParams(logicalVolumeIdRegexp, val)["idx"]
idx, err := strconv.Atoi(idxStr)
if err != nil {
return nil, errors.Errorf("index %q to int: %v", idxStr, err)
}
blockDev, err := getLogicVolumeDeviceById(adapter.hostNum, idx, adapter.getTerm())
if err != nil {
return nil, err
}
lvs = append(lvs, &raiddrivers.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
BlockDev: blockDev,
})
}
}
return lvIdx
return lvs, nil
}
func getLogicVolumeDeviceById(hostNum, scsiId int, term *ssh.Client) (string, error) {
items, err := raiddrivers.SGMap(term)
if err != nil {
return "", err
}
isMatch := func(item api.SGMapItem) bool {
return item.HostNumber == hostNum && item.SCSIId == scsiId
}
for _, item := range items {
if isMatch(item) {
return item.LinuxDeviceName, nil
}
}
return "", errors.Errorf("Not found SG item by id: %d:%d", hostNum, scsiId)
}
func (adapter *MegaRaidAdaptor) PreBuildRaid(confs []*api.BaremetalDiskConfig) error {
@@ -384,7 +529,6 @@ func (adapter *MegaRaidAdaptor) megacliBuildRaid10(devs []*baremetal.BaremetalSt
func (adapter *MegaRaidAdaptor) storcliBuildRaid(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig, level uint) error {
args := []string{}
args = append(args, fmt.Sprintf("/c%d", adapter.index))
args = append(args, "add", "vd", fmt.Sprintf("type=r%d", level))
args = append(args, adapter.conf2ParamsStorcliSize(conf)...)
labels := []string{}
@@ -396,9 +540,12 @@ func (adapter *MegaRaidAdaptor) storcliBuildRaid(devs []*baremetal.BaremetalStor
args = append(args, "PDperArray=2")
}
args = append(args, adapter.conf2ParamsStorcli(conf)...)
cmd := GetCommand2(args...)
cmd, err := adapter.GetStorcliCommand(args...)
if err != nil {
return errors.Wrapf(err, "build raid %d", level)
}
log.Infof("_storcliBuildRaid command: %s", cmd)
_, err := adapter.remoteRun(cmd)
_, err = adapter.remoteRun(cmd)
return err
}
@@ -451,8 +598,86 @@ func (adapter *MegaRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage
return cliBuildRaid(devs, nil, adapter.megacliBuildNoRaid, adapter.storcliBuildNoRaid)
}
type StorcliAdaptor struct {
Controller int
SN string
}
func newStorcliAdaptor() *StorcliAdaptor {
return &StorcliAdaptor{
Controller: -1,
SN: "",
}
}
func (a *StorcliAdaptor) isComplete() bool {
return a.Controller >= 0 && a.SN != ""
}
func (a *StorcliAdaptor) parseLine(l string) {
parts := strings.Split(l, " = ")
if len(parts) != 2 {
return
}
key := parts[0]
val := parts[1]
switch key {
case "Controller":
a.Controller, _ = strconv.Atoi(val)
case "Serial Number":
a.SN = val
}
}
func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
ret := make(map[string]*StorcliAdaptor)
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Serial Number)\s='`)
lines, err := raid.term.Run(cmd)
if err != nil {
return nil, errors.Wrap(err, "Get storcli adapter")
}
adapter := newStorcliAdaptor()
for _, l := range lines {
adapter.parseLine(l)
if adapter.isComplete() {
ret[adapter.SN] = adapter
adapter = newStorcliAdaptor()
}
}
return ret, nil
}
func (adapter *MegaRaidAdaptor) storcliCtrlIndex() (int, error) {
if adapter.storcliIndex >= 0 {
return adapter.storcliIndex, nil
}
storcliAdaps, err := adapter.raid.GetStorcliAdaptor()
if err != nil {
return -1, errors.Wrap(err, "Get all Storcli adaptor")
}
storAdap, ok := storcliAdaps[adapter.sn]
if !ok {
return -1, errors.Errorf("Not found storcli adaptor by SN %q", adapter.sn)
}
return storAdap.Controller, nil
}
func (adapter *MegaRaidAdaptor) GetStorcliCommand(args ...string) (string, error) {
controllerIdx, err := adapter.storcliCtrlIndex()
if err != nil {
return "", errors.Errorf("Adapter %d get storcli controller index: %v", adapter.index, err)
}
nargs := []string{fmt.Sprintf("/c%d", controllerIdx)}
nargs = append(nargs, args...)
return GetCommand2(nargs...), nil
}
func (adapter *MegaRaidAdaptor) storcliIsJBODEnabled() bool {
cmd := GetCommand2(fmt.Sprintf("/c%d", adapter.index), "show", "jbod")
cmd, err := adapter.GetStorcliCommand("show", "jbod")
if err != nil {
log.Errorf("get storcli controller cmd: %v", err)
return false
}
lines, err := adapter.remoteRun(cmd)
if err != nil {
log.Errorf("storcliIsJBODEnabled error: %s", err)
@@ -476,8 +701,12 @@ func (adapter *MegaRaidAdaptor) storcliEnableJBOD(enable bool) bool {
if enable {
val = "on"
}
cmd := GetCommand2(fmt.Sprintf("/c%d", adapter.index), "set", fmt.Sprintf("jbod=%s", val))
_, err := adapter.remoteRun(cmd)
cmd, err := adapter.GetStorcliCommand("set", fmt.Sprintf("jbod=%s", val))
if err != nil {
log.Errorf("get storcli controller cmd: %v", err)
return false
}
_, err = adapter.remoteRun(cmd)
if err != nil {
log.Errorf("EnableJBOD %v fail: %v", enable, err)
return false
@@ -496,7 +725,7 @@ func (adapter *MegaRaidAdaptor) storcliBuildJBOD(devs []*baremetal.BaremetalStor
}
cmds := []string{}
for _, d := range devs {
cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.index, d.Enclosure, d.Slot))
cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.storcliIndex, d.Enclosure, d.Slot))
cmds = append(cmds, cmd)
}
log.Infof("storcliBuildJBOD cmds: %v", cmds)
@@ -518,12 +747,14 @@ func (adapter *MegaRaidAdaptor) storcliBuildNoRaid(devs []*baremetal.BaremetalSt
labels = append(labels, GetSpecString(dev))
}
args := []string{
fmt.Sprintf("/c%d", adapter.index),
"add", "vd", "each", "type=raid0",
fmt.Sprintf("drives=%s", strings.Join(labels, ",")),
"wt", "nora", "direct",
}
cmd := GetCommand2(args...)
cmd, err := adapter.GetStorcliCommand(args...)
if err != nil {
return errors.Wrapf(err, "build none raid")
}
_, err = adapter.remoteRun(cmd)
return err
}
@@ -602,8 +833,8 @@ func (adapter *MegaRaidAdaptor) RemoveLogicVolumes() error {
if err != nil {
return err
}
for i := len(lvIdx) - 1; i >= 0; i-- {
cmd := GetCommand("-CfgLdDel", fmt.Sprintf("-L%d", i), "-Force", fmt.Sprintf("-a%d", adapter.index))
for _, i := range raiddrivers.ReverseLogicalArray(lvIdx) {
cmd := GetCommand("-CfgLdDel", fmt.Sprintf("-L%d", i.Index), "-Force", fmt.Sprintf("-a%d", adapter.index))
cmds = append(cmds, cmd)
}
if len(cmds) > 0 {
@@ -630,8 +861,8 @@ def _storcli_clear_jbod_disks(self):
func (adapter *MegaRaidAdaptor) megacliClearJBODDisks() error {
devIds := []string{}
for _, dev := range adapter.devs {
devIds = append(devIds, GetSpecString(dev.ToBaremetalStorage()))
for idx, dev := range adapter.devs {
devIds = append(devIds, GetSpecString(dev.ToBaremetalStorage(idx)))
}
cmd := GetCommand("-PDMakeGood", fmt.Sprintf("-PhysDrv[%s]", strings.Join(devIds, ",")), "-Force", fmt.Sprintf("-a%d", adapter.index))
_, err := adapter.remoteRun(cmd)
@@ -674,7 +905,7 @@ func (raid *MegaRaid) GetName() string {
}
func (raid *MegaRaid) ParsePhyDevs() error {
if !utils.IsInStringArray("megaraid_sas", raiddrivers.GetModules(raid.term)) {
if !utils.IsInStringArray(raiddrivers.MODULE_MEGARAID, raiddrivers.GetModules(raid.term)) {
return fmt.Errorf("Not found megaraid_sas module")
}
cmd := GetCommand("-PDList", "-aALL")
@@ -692,18 +923,15 @@ func (raid *MegaRaid) ParsePhyDevs() error {
func (raid *MegaRaid) parsePhyDevs(lines []string) error {
phyDev := NewMegaRaidPhyDev()
var adapter *MegaRaidAdaptor
var err error
for _, line := range lines {
matches := adapterPatter.FindStringSubmatch(line)
if len(matches) != 0 {
paramsMap := make(map[string]string)
for i, name := range sizePattern.SubexpNames() {
if i > 0 && i <= len(matches) {
paramsMap[name] = matches[i]
}
}
adapterStr := paramsMap["idx"]
adapterStr := regutils2.GetParams(adapterPatter, line)["idx"]
if adapterStr != "" {
adapterInt, _ := strconv.Atoi(adapterStr)
adapter = NewMegaRaidAdaptor(adapterInt, raid)
adapter, err = NewMegaRaidAdaptor(adapterInt, raid)
if err != nil {
return errors.Wrapf(err, "New raid adapter %d", adapterInt)
}
raid.adapters = append(raid.adapters, adapter)
} else if phyDev.parseLine(line) && phyDev.isComplete() {
if adapter == nil {
@@ -715,43 +943,30 @@ func (raid *MegaRaid) parsePhyDevs(lines []string) error {
phyDev = NewMegaRaidPhyDev()
}
}
for _, dev := range adapter.devs {
if err := raid.addPhyDevStripSize(dev); err != nil {
return fmt.Errorf("addPhyDevStripSize: %v", err)
for _, adapter := range raid.adapters {
if err := adapter.addPhyDevsStripSize(); err != nil {
log.Errorf("Adapter %d fill phsical devices strip size: %v", adapter.GetIndex(), err)
}
}
return nil
}
func (raid *MegaRaid) addPhyDevStripSize(phyDev *MegaRaidPhyDev) error {
func (adapter *MegaRaidAdaptor) addPhyDevsStripSize() error {
grepCmd := []string{"grep", "-iE", "'^(Min|Max) Strip Size'"}
args := []string{"-adpallinfo", "-aall", "|"}
args := []string{"-adpallinfo", fmt.Sprintf("-a%d", adapter.index), "|"}
args = append(args, grepCmd...)
cmd := GetCommand(args...)
ret, err := raid.term.Run(cmd)
ret, err := adapter.remoteRun(cmd)
if err != nil {
return fmt.Errorf("addPhyDevStripSize error: %v", err)
}
return phyDev.parseStripSize(ret)
}
/*func (raid *MegaRaid) GetPhyDevs() []*MegaRaidPhyDev {
devs := make([]*MegaRaidPhyDev, 0)
for _, ada := range raid.adapters {
devs = append(devs, ada.GetPhyDevs()...)
for _, dev := range adapter.devs {
if err := dev.parseStripSize(ret); err != nil {
return err
}
}
return devs
}*/
//func (raid *MegaRaid) ParseLogicVolumes() bool {
//cmd := GetCommand("-LDInfo", "-Lall", "-aALL")
//ret, err := raid.term.Run(cmd)
//if err != nil {
//return false
//}
//raid.parseLogicVolumes(ret)
//return true
//}
return nil
}
func (raid *MegaRaid) CleanRaid() error {
for _, adapter := range raid.adapters {

View File

@@ -87,8 +87,8 @@ func (dev *MarvelRaidPhyDev) isComplete() bool {
return true
}
func (dev *MarvelRaidPhyDev) ToBaremetalStorage() *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage()
func (dev *MarvelRaidPhyDev) ToBaremetalStorage(idx int) *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage(idx)
s.Slot = dev.slot
return s
}
@@ -137,13 +137,13 @@ func (adapter *MarvelRaidAdaptor) parsePhyDevs(lines []string) error {
func (adapter *MarvelRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
ret := []*baremetal.BaremetalStorage{}
for _, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage())
for idx, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage(idx))
}
return ret
}
func (adapter *MarvelRaidAdaptor) GetLogicVolumes() ([]int, error) {
func (adapter *MarvelRaidAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) {
cmd := GetCommand("info", "-o", "vd")
ret, err := adapter.raid.term.Run(cmd)
if err != nil {
@@ -152,9 +152,9 @@ func (adapter *MarvelRaidAdaptor) GetLogicVolumes() ([]int, error) {
return adapter.parseLogicVolumes(ret)
}
func (adapter *MarvelRaidAdaptor) parseLogicVolumes(lines []string) ([]int, error) {
lvIdx := []int{}
usedDevs := []int{}
func (adapter *MarvelRaidAdaptor) parseLogicVolumes(lines []string) ([]*raid.RaidLogicalVolume, error) {
lvIdx := make([]*raid.RaidLogicalVolume, 0)
usedDevs := make([]*raid.RaidLogicalVolume, 0)
for _, line := range lines {
key, val := stringutils.SplitKeyValue(line)
if key != "" {
@@ -163,14 +163,20 @@ func (adapter *MarvelRaidAdaptor) parseLogicVolumes(lines []string) ([]int, erro
if err != nil {
return nil, err
}
lvIdx = append(lvIdx, idx)
lvIdx = append(lvIdx, &raid.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
})
} else if key == "PD RAID setup" {
for _, d := range strings.Split(val, " ") {
idx, err := strconv.Atoi(d)
if err != nil {
return nil, err
}
usedDevs = append(usedDevs, idx)
usedDevs = append(usedDevs, &raid.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
})
}
}
}
@@ -186,9 +192,9 @@ func (adapter *MarvelRaidAdaptor) RemoveLogicVolumes() error {
if err != nil {
return fmt.Errorf("Failed to get logic volumes: %v", err)
}
for i := len(lvs) - 1; i >= 0; i-- {
if err := adapter.removeLogicVolume(i); err != nil {
return fmt.Errorf("Remove %d logical volume: %v", i, err)
for _, i := range raid.ReverseLogicalArray(lvs) {
if err := adapter.removeLogicVolume(i.Index); err != nil {
return fmt.Errorf("Remove %#v logical volume: %v", i, err)
}
}
return nil

View File

@@ -17,11 +17,27 @@ package raid
import (
"strings"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/baremetal"
"yunion.io/x/onecloud/pkg/util/ssh"
"yunion.io/x/onecloud/pkg/util/sysutils"
)
const (
MODULE_MEGARAID = "megaraid_sas"
MODULE_HPSA = "hpsa"
MODULE_MPT2SAS = "mpt2sas"
MODULE_MPT3SAS = "mpt3sas"
)
const (
MaxUint = ^uint(0)
MaxInt = int(MaxUint >> 1)
UnknownLogicalVolumeIndex = MaxInt
)
type RaidDriverFactory func(term *ssh.Client) IRaidDriver
@@ -74,7 +90,7 @@ func (dev *RaidBasePhyDev) IsComplete() bool {
return true
}
func (dev *RaidBasePhyDev) ToBaremetalStorage() *baremetal.BaremetalStorage {
func (dev *RaidBasePhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalStorage {
return &baremetal.BaremetalStorage{
Adapter: dev.Adapter,
Status: dev.Status,
@@ -103,3 +119,28 @@ func GetModules(term *ssh.Client) []string {
}
return ret
}
func ReverseLogicalArray(input []*RaidLogicalVolume) []*RaidLogicalVolume {
s := make([]*RaidLogicalVolume, len(input))
for i := range input {
s[i] = input[i]
}
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}
type RaidLogicalVolume struct {
Index int
Adapter int
BlockDev string
}
func SGMap(term *ssh.Client) ([]compute.SGMapItem, error) {
lines, err := term.Run("/usr/bin/sg_map -x")
if err != nil {
return nil, errors.Wrap(err, "run sg_map")
}
return sysutils.ParseSGMap(lines), nil
}

View File

@@ -0,0 +1,52 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package raid
import (
"reflect"
"testing"
)
func TestReverseLogicalArray(t *testing.T) {
tests := []struct {
name string
input []*RaidLogicalVolume
want []*RaidLogicalVolume
}{
{
name: "empty input",
input: []*RaidLogicalVolume{},
want: []*RaidLogicalVolume{},
},
{
name: "reverse",
input: []*RaidLogicalVolume{
{Index: 1},
{Index: 2},
},
want: []*RaidLogicalVolume{
{Index: 2},
{Index: 1},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ReverseLogicalArray(tt.input); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ReverseIntArray() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -115,8 +115,8 @@ func (dev *Mpt2SASRaidPhyDev) isComplete() bool {
return true
}
func (dev *Mpt2SASRaidPhyDev) ToBaremetalStorage() *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage()
func (dev *Mpt2SASRaidPhyDev) ToBaremetalStorage(idx int) *baremetal.BaremetalStorage {
s := dev.RaidBasePhyDev.ToBaremetalStorage(idx)
s.Slot = dev.slot
s.Enclosure = dev.enclosure
s.Block = int64(dev.block)
@@ -176,13 +176,13 @@ func (adapter *Mpt2SASRaidAdaptor) parsePhyDevs(lines []string) error {
func (adapter *Mpt2SASRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
ret := []*baremetal.BaremetalStorage{}
for _, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage())
for idx, dev := range adapter.devs {
ret = append(ret, dev.ToBaremetalStorage(idx))
}
return ret
}
func (adapter *Mpt2SASRaidAdaptor) GetLogicVolumes() ([]int, error) {
func (adapter *Mpt2SASRaidAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) {
cmd := adapter.raid.GetCommand(fmt.Sprintf("%d", adapter.index), "DISPLAY")
ret, err := adapter.raid.term.Run(cmd)
if err != nil {
@@ -191,24 +191,33 @@ func (adapter *Mpt2SASRaidAdaptor) GetLogicVolumes() ([]int, error) {
return adapter.parseLogicVolumes(ret)
}
func (adapter *Mpt2SASRaidAdaptor) parseLogicVolumes(lines []string) ([]int, error) {
lvIdx := []int{}
usedDevs := []int{}
func (adapter *Mpt2SASRaidAdaptor) parseLogicVolumes(lines []string) ([]*raid.RaidLogicalVolume, error) {
lvIdx := []*raid.RaidLogicalVolume{}
usedDevs := []*raid.RaidLogicalVolume{}
for _, line := range lines {
key, val := stringutils.SplitKeyValue(line)
if key != "" && key == "Volume ID" {
idx, _ := strconv.Atoi(val)
lvIdx = append(lvIdx, idx)
lvIdx = append(lvIdx, &raid.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
})
} else if regexp.MustCompile(`PHY\[\d+\] Enclosure#/Slot#`).MatchString(key) {
idx, _ := strconv.Atoi(val)
usedDevs = append(usedDevs, idx)
usedDevs = append(usedDevs, &raid.RaidLogicalVolume{
Index: idx,
Adapter: adapter.index,
})
}
}
if len(adapter.devs) < len(usedDevs) {
return nil, fmt.Errorf("adapter current dev %d < usedDevs %d", len(adapter.devs), len(usedDevs))
}
for i := 0; i < len(adapter.devs)-len(usedDevs); i++ {
lvIdx = append(lvIdx, -1)
lvIdx = append(lvIdx, &raid.RaidLogicalVolume{
Index: -1,
Adapter: adapter.index,
})
}
return lvIdx, nil
}
@@ -231,8 +240,8 @@ func (adapter *Mpt2SASRaidAdaptor) setBootIR() error {
if err != nil {
return err
}
if len(lvs) > 0 && lvs[0] > 0 {
args := []string{fmt.Sprintf("%d", adapter.index), "BOOTIR", fmt.Sprintf("%d", lvs[0])}
if len(lvs) > 0 && lvs[0].Index > 0 {
args := []string{fmt.Sprintf("%d", adapter.index), "BOOTIR", fmt.Sprintf("%d", lvs[0].Index)}
cmd := adapter.raid.GetCommand(args...)
_, err := adapter.raid.term.Run(cmd)
return err
@@ -315,9 +324,9 @@ func (r *Mpt2SASRaid) GetName() string {
}
func (r *Mpt2SASRaid) ParsePhyDevs() error {
if r.modulePCIProbed("mpt2sas") {
if r.modulePCIProbed(raid.MODULE_MPT2SAS) {
r.utility = "/opt/lsi/sas2ircu"
} else if r.modulePCIProbed("mpt3sas") {
} else if r.modulePCIProbed(raid.MODULE_MPT3SAS) {
r.utility = "/opt/lsi/sas3ircu"
} else {
return fmt.Errorf("Not probe mpt2sas or mpt3sas kernel module")

View File

@@ -109,6 +109,8 @@ func ParseDiskConfig(diskStr string, idx int) (*compute.DiskConfig, error) {
diskConfig.Mountpoint = p
} else if p == "autoextend" {
diskConfig.SizeMb = -1
} else if utils.IsInStringArray(p, compute.STORAGE_ALL_TYPES) {
diskConfig.Backend = p
} else if strings.HasPrefix(p, "snapshot-") {
// HACK: use snapshot creat disk format snapshot-id
// example: snapshot-3140cecb-ccc4-4865-abae-3a5ba8c69d9b

View File

@@ -0,0 +1,32 @@
package db
import (
"reflect"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/utils"
)
func FetchModelExtraCountProperties(model IModel, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
selfValue := reflect.ValueOf(model)
selfType := reflect.TypeOf(model)
for i := 0; i < selfValue.NumMethod(); i += 1 {
methodValue := selfValue.Method(i)
methodType := methodValue.Type()
if methodType.NumIn() != 0 || methodType.NumOut() != 2 {
continue
}
methodName := selfType.Method(i).Name
tokens := utils.CamelSplitTokens(methodName)
if len(tokens) < 3 {
continue
}
if strings.EqualFold(tokens[0], "get") && strings.EqualFold(tokens[len(tokens)-1], "count") {
resName := strings.ToLower(strings.Join(tokens[1:], "_"))
outs := methodValue.Call([]reflect.Value{})
extra.Add(jsonutils.NewInt(outs[0].Int()), resName)
}
}
return extra
}

View File

@@ -466,15 +466,25 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
if err != nil {
return nil, err
}
totalCnt := int64(q.Count())
totalCnt, err := q.CountWithError()
if err != nil {
return nil, err
}
// log.Debugf("total count %d", totalCnt)
if totalCnt == 0 {
emptyList := modules.ListResult{Data: []jsonutils.JSONObject{}}
return &emptyList, nil
}
if totalCnt > maxLimit && (limit <= 0 || limit > maxLimit) {
if int64(totalCnt) > maxLimit && (limit <= 0 || limit > maxLimit) {
limit = maxLimit
}
// export data only
exportLimit, err := query.Int("export_limit")
if query.Contains("export_keys") && err == nil {
limit = exportLimit
}
orderBy := jsonutils.GetQueryStringArray(queryDict, "order_by")
if len(orderBy) == 0 {
colSpec := manager.TableSpec().ColumnSpec("id")
@@ -524,14 +534,14 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
return nil, httperrors.NewGeneralError(err)
}
if len(retList) != retCount {
totalCnt = int64(len(retList))
totalCnt = len(retList)
}
paginate := false
if !customizeFilters.IsEmpty() {
// query not use Limit and Offset, do manual pagination
paginate = true
}
return calculateListResult(retList, totalCnt, limit, offset, paginate), nil
return calculateListResult(retList, int64(totalCnt), limit, offset, paginate), nil
}
func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64, paginate bool) *modules.ListResult {
@@ -883,7 +893,11 @@ func doCreateItem(manager IModelManager, ctx context.Context, userCred mcclient.
generateName, _ := dataDict.GetString("generate_name")
if len(generateName) > 0 {
dataDict.Remove("generate_name")
dataDict.Add(jsonutils.NewString(GenerateName(manager, ownerProjId, generateName)), "name")
newName, err := GenerateName(manager, ownerProjId, generateName)
if err != nil {
return nil, err
}
dataDict.Add(jsonutils.NewString(newName), "name")
} else {
name, _ := data.GetString("name")
if len(name) > 0 {

View File

@@ -46,7 +46,10 @@ func FetchJointByIds(manager IJointModelManager, masterId, slaveId string, query
cond := sqlchemy.AND(sqlchemy.Equals(masterField, masterId), sqlchemy.Equals(slaveField, slaveId))
q = q.Filter(cond)
q = manager.FilterByParams(q, query)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
return nil, sqlchemy.ErrDuplicateEntry
} else if count == 0 {
@@ -62,7 +65,10 @@ func FetchJointByIds(manager IJointModelManager, masterId, slaveId string, query
func FetchById(manager IModelManager, idStr string) (IModel, error) {
q := manager.Query()
q = manager.FilterById(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
obj, err := NewModelObject(manager)
if err != nil {
@@ -88,10 +94,16 @@ func FetchByName(manager IModelManager, userCred mcclient.IIdentityProvider, idS
}
q := manager.Query()
q = manager.FilterByName(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
q = manager.FilterByOwner(q, owner)
count = q.Count()
count, err = q.CountWithError()
if err != nil {
return nil, err
}
}
if count == 1 {
obj, err := NewModelObject(manager)
@@ -133,7 +145,10 @@ func fetchItemById(manager IModelManager, ctx context.Context, userCred mcclient
}
}
q = manager.FilterById(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
item, err := NewModelObject(manager)
if err != nil {
@@ -161,10 +176,16 @@ func fetchItemByName(manager IModelManager, ctx context.Context, userCred mcclie
}
}
q = manager.FilterByName(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
q = manager.FilterByOwner(q, manager.GetOwnerId(userCred))
count = q.Count()
count, err = q.CountWithError()
if err != nil {
return nil, err
}
}
if count == 1 {
item, err := NewModelObject(manager)

View File

@@ -147,10 +147,10 @@ func (manager *SMetadataManager) ListItemFilter(ctx context.Context, q *sqlchemy
conditions := []sqlchemy.ICondition{}
admin := jsonutils.QueryBoolean(query, "admin", false)
for _, resource := range resources {
if manager, ok := ResourceMap[resource]; ok {
resourceView := manager.Query().SubQuery()
prefix := sqlchemy.NewStringField(fmt.Sprintf("%s::", manager.Keyword()))
field := sqlchemy.CONCAT(manager.Keyword(), prefix, resourceView.Field("id"))
if man, ok := ResourceMap[resource]; ok {
resourceView := man.Query().SubQuery()
prefix := sqlchemy.NewStringField(fmt.Sprintf("%s::", man.Keyword()))
field := sqlchemy.CONCAT(man.Keyword(), prefix, resourceView.Field("id"))
sq := resourceView.Query(field)
if !admin || !IsAdminAllowList(userCred, manager) {
ownerId := manager.GetOwnerId(userCred)
@@ -171,6 +171,18 @@ func (manager *SMetadataManager) ListItemFilter(ctx context.Context, q *sqlchemy
q = q.Filter(sqlchemy.Startswith(q.Field("key"), prefix))
}
}
withConditions := []sqlchemy.ICondition{}
for args, prefix := range map[string]string{"with_sys_meta": SYS_TAG_PREFIX, "with_cloud_meta": CLOUD_TAG_PREFIX, "with_user_meta": USER_TAG_PREFIX} {
if jsonutils.QueryBoolean(query, args, false) {
withConditions = append(withConditions, sqlchemy.Startswith(q.Field("key"), prefix))
}
}
if len(withConditions) > 0 {
q = q.Filter(sqlchemy.OR(withConditions...))
}
return q, nil
}
@@ -270,9 +282,6 @@ func (manager *SMetadataManager) SetValues(ctx context.Context, obj IModel, stor
changes := make([]sMetadataChange, 0)
for key, value := range store {
if strings.HasPrefix(key, SYS_TAG_PREFIX) && (userCred == nil || !IsAdminAllowGetSpec(userCred, obj, "metadata")) {
return nil, httperrors.NewForbiddenError("Ordinary users can't set the tags that begin with an underscore")
}
valStr := stringutils.Interface2String(value)
valStrLower := strings.ToLower(valStr)

View File

@@ -29,7 +29,6 @@ func RegisterModelManager(modelMan IModelManager) {
globalTables = make(map[string]IModelManager)
}
mustCheckModelManager(modelMan)
log.Infof("Register model %s", modelMan.Keyword())
globalTables[modelMan.Keyword()] = modelMan
}
@@ -60,8 +59,7 @@ func mustCheckModelManager(modelMan IModelManager) {
func CheckSync(autoSync bool) bool {
log.Infof("Start check database ...")
allSqls := make([]string, 0)
for modelName, modelMan := range globalTables {
log.Infof("# check table of model %s", modelName)
for _, modelMan := range globalTables {
tableSpec := modelMan.TableSpec()
sqls := tableSpec.SyncSQL()
for _, sql := range sqls {

View File

@@ -23,13 +23,17 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
)
func isNameUnique(manager IModelManager, owner string, name string) bool {
func isNameUnique(manager IModelManager, owner string, name string) (bool, error) {
q := manager.Query()
q = manager.FilterByName(q, name)
if !consts.IsGlobalVirtualResourceNamespace() {
q = manager.FilterByOwner(q, owner)
}
return q.Count() == 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt == 0, nil
}
func NewNameValidator(manager IModelManager, ownerProjId string, name string) error {
@@ -37,13 +41,17 @@ func NewNameValidator(manager IModelManager, ownerProjId string, name string) er
if err != nil {
return err
}
if !isNameUnique(manager, ownerProjId, name) {
uniq, err := isNameUnique(manager, ownerProjId, name)
if err != nil {
return err
}
if !uniq {
return httperrors.NewDuplicateNameError("name", name)
}
return nil
}
func isAlterNameUnique(model IModel, name string) bool {
func isAlterNameUnique(model IModel, name string) (bool, error) {
manager := model.GetModelManager()
q := manager.Query()
q = manager.FilterByName(q, name)
@@ -51,7 +59,11 @@ func isAlterNameUnique(model IModel, name string) bool {
q = manager.FilterByOwner(q, model.GetOwnerProjectId())
}
q = manager.FilterByNotId(q, model.GetId())
return q.Count() == 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt == 0, nil
}
func alterNameValidator(model IModel, name string) error {
@@ -59,13 +71,17 @@ func alterNameValidator(model IModel, name string) error {
if err != nil {
return err
}
if !isAlterNameUnique(model, name) {
uniq, err := isAlterNameUnique(model, name)
if err != nil {
return err
}
if !uniq {
return httperrors.NewDuplicateNameError("name", name)
}
return nil
}
func GenerateName(manager IModelManager, ownerProjId string, hint string) string {
func GenerateName(manager IModelManager, ownerProjId string, hint string) (string, error) {
_, pattern, patternLen := stringutils.ParseNamePattern(hint)
var name string
idx := 1
@@ -75,9 +91,15 @@ func GenerateName(manager IModelManager, ownerProjId string, hint string) string
name = fmt.Sprintf(pattern, idx)
idx += 1
}
for !isNameUnique(manager, ownerProjId, name) {
for {
uniq, err := isNameUnique(manager, ownerProjId, name)
if err != nil {
return "", err
}
if uniq {
return name, nil
}
name = fmt.Sprintf(pattern, idx)
idx += 1
}
return name
}

View File

@@ -32,16 +32,18 @@ import (
)
const (
ACT_CREATE = "create"
ACT_DELETE = "delete"
ACT_UPDATE = "update"
ACT_FETCH = "fetch"
ACT_ENABLE = "enable"
ACT_DISABLE = "disable"
ACT_OFFLINE = "offline"
ACT_ONLINE = "online"
ACT_ATTACH = "attach"
ACT_DETACH = "detach"
ACT_CREATE = "create"
ACT_DELETE = "delete"
ACT_UPDATE = "update"
ACT_FETCH = "fetch"
ACT_ENABLE = "enable"
ACT_DISABLE = "disable"
ACT_OFFLINE = "offline"
ACT_ONLINE = "online"
ACT_ATTACH = "attach"
ACT_DETACH = "detach"
ACT_ATTACH_FAIL = "attach_fail"
ACT_DETACH_FAIL = "detach_fail"
ACT_SYNC_UPDATE = "sync_update"
ACT_SYNC_CREATE = "sync_create"
@@ -49,6 +51,8 @@ const (
ACT_START_CREATE_BACKUP = "start_create_backup"
ACT_CREATE_BACKUP = "create_backup"
ACT_CREATE_BACKUP_FAILED = "create_backup_failed"
ACT_DELETE_BACKUP = "delete_backup"
ACT_DELETE_BACKUP_FAILED = "delete_backup_failed"
ACT_UPDATE_STATUS = "updatestatus"
ACT_STARTING = "starting"
@@ -116,6 +120,9 @@ const (
ACT_SET_METADATA = "set_meta"
ACT_DEL_METADATA = "del_meta"
ACT_VM_DEPLOY = "deploy"
ACT_VM_DEPLOY_FAIL = "deploy_fail"
ACT_REBUILDING_ROOT = "rebuilding_root"
ACT_REBUILD_ROOT = "rebuild_root"
ACT_REBUILD_ROOT_FAIL = "rebuild_root_fail"

View File

@@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package guestman
package db
import (
"testing"
"time"
)
func TestSKVMGuestInstance_getPid(t *testing.T) {
manager := NewGuestManager(nil, "/opt/cloud/workspace/servers")
s := NewKVMGuestInstance("05b787e9-b78e-4ebc-8128-04f55d37306f", manager)
t.Logf("Guest is ->> %d", s.GetPid())
type IPendingDeletable interface {
GetPendingDeleted() bool
GetPendingDeletedAt() time.Time
}

View File

@@ -99,7 +99,10 @@ func (manager *SStandaloneResourceBaseManager) FetchByIdOrName(userCred mcclient
func (manager *SStandaloneResourceBaseManager) FetchByExternalId(idStr string) (IStandaloneModel, error) {
q := manager.Query().Equals("external_id", idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
obj, err := NewModelObject(manager)
if err != nil {
@@ -153,7 +156,7 @@ func (manager *SStandaloneResourceBaseManager) ListItemFilter(ctx context.Contex
}
if len(tags) > 0 {
metadataView := Metadata.Query("id")
metadataView := Metadata.Query()
idx := 0
for k, v := range tags {
if idx == 0 {
@@ -171,25 +174,26 @@ func (manager *SStandaloneResourceBaseManager) ListItemFilter(ctx context.Contex
}
idx++
}
metadataView = metadataView.Filter(sqlchemy.Like(metadataView.Field("id"), manager.Keyword()+"::%")).Distinct()
resourceIds := []string{}
rows, err := metadataView.Rows()
if err != nil {
log.Errorf("query metadata ids error: %v", err)
return nil, err
}
defer rows.Close()
for rows.Next() {
var metadataID string
err = rows.Scan(&metadataID)
if err != nil {
log.Errorf("get metadata id scan error: %v", err)
return nil, err
}
resourceIds = append(resourceIds, strings.TrimLeft(metadataID, manager.Keyword()+"::"))
}
q = q.Filter(sqlchemy.In(q.Field("id"), resourceIds))
metadatas := metadataView.SubQuery()
fieldName := fmt.Sprintf("%s_id", manager.Keyword())
metadataSQ := metadatas.Query(
sqlchemy.REPLACE(fieldName, metadatas.Field("id"), manager.Keyword()+"::", ""),
)
sq := metadataSQ.Filter(sqlchemy.Like(metadatas.Field("id"), manager.Keyword()+"::%")).Distinct()
q = q.Filter(sqlchemy.In(q.Field("id"), sq))
}
if withoutUserMeta, _ := query.Bool("without_user_meta"); withoutUserMeta {
metadatas := Metadata.Query().SubQuery()
fieldName := fmt.Sprintf("%s_id", manager.Keyword())
metadataSQ := metadatas.Query(
sqlchemy.REPLACE(fieldName, metadatas.Field("id"), manager.Keyword()+"::", ""),
)
sq := metadataSQ.Filter(sqlchemy.Like(metadatas.Field("key"), USER_TAG_PREFIX+"%")).Distinct()
q.Filter(sqlchemy.NotIn(q.Field("id"), sq))
}
return q, nil
}
@@ -227,18 +231,10 @@ func (model *SStandaloneResourceBase) GetMetadataJson(key string, userCred mccli
}
func (model *SStandaloneResourceBase) SetMetadata(ctx context.Context, key string, value interface{}, userCred mcclient.TokenCredential) error {
if Metadata.IsSystemAdminKey(key) && !IsAdminAllowPerform(userCred, model, "metadata") {
return httperrors.NewNotSufficientPrivilegeError("cannot set system key")
}
return Metadata.SetValue(ctx, model, key, value, userCred)
}
func (model *SStandaloneResourceBase) SetAllMetadata(ctx context.Context, dictstore map[string]interface{}, userCred mcclient.TokenCredential) error {
for k := range dictstore {
if Metadata.IsSystemAdminKey(k) && !IsAdminAllowPerform(userCred, model, "metadata") {
return httperrors.NewNotSufficientPrivilegeError("not allow to set system key %s", k)
}
}
return Metadata.SetValuesWithLog(ctx, model, dictstore, userCred)
}
@@ -290,6 +286,10 @@ func (model *SStandaloneResourceBase) PerformMetadata(ctx context.Context, userC
}
dictStore := make(map[string]interface{})
for k, v := range dictMap {
// 已双下滑线开头的metadata是系统内置普通用户不可添加只能查看
if strings.HasPrefix(k, SYS_TAG_PREFIX) && (userCred == nil || !IsAdminAllowPerform(userCred, model, "metadata")) {
return nil, httperrors.NewForbiddenError("not allow to set system key, please remove the underscore at the beginning")
}
dictStore[k], _ = v.GetString()
}
err = model.SetAllMetadata(ctx, dictStore, userCred)
@@ -311,7 +311,7 @@ func (model *SStandaloneResourceBase) PerformUserMetadata(ctx context.Context, u
}
dictStore := make(map[string]interface{})
for k, v := range dictMap {
dictStore["user:"+k], _ = v.GetString()
dictStore[USER_TAG_PREFIX+k], _ = v.GetString()
}
err = model.SetUserMetadataValues(ctx, dictStore, userCred)
return nil, err

View File

@@ -20,6 +20,7 @@ import (
"fmt"
"net/http"
"reflect"
"runtime/debug"
"strings"
"time"
@@ -75,9 +76,9 @@ type STask struct {
ObjName string `width:"128" charset:"utf8" nullable:"false" list:"user"` // Column(VARCHAR(128, charset='utf8'), nullable=False)
ObjId string `width:"128" charset:"ascii" nullable:"false" list:"user" index:"true"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False)
TaskName string `width:"64" charset:"ascii" nullable:"false" list:"user"` // Column(VARCHAR(64, charset='ascii'), nullable=False)
UserCred mcclient.TokenCredential `width:"1024" charset:"ascii" nullable:"false" get:"user"` // Column(VARCHAR(1024, charset='ascii'), nullable=False)
UserCred mcclient.TokenCredential `width:"1024" charset:"utf8" nullable:"false" get:"user"` // Column(VARCHAR(1024, charset='ascii'), nullable=False)
// OwnerCred string `width:"512" charset:"ascii" nullable:"true"` // Column(VARCHAR(512, charset='ascii'), nullable=True)
Params *jsonutils.JSONDict `charset:"ascii" length:"medium" nullable:"false" get:"user"` // Column(MEDIUMTEXT(charset='ascii'), nullable=False)
Params *jsonutils.JSONDict `charset:"utf8" length:"medium" nullable:"false" get:"user"` // Column(MEDIUMTEXT(charset='ascii'), nullable=False)
Stage string `width:"64" charset:"ascii" nullable:"false" default:"on_init" list:"user"` // Column(VARCHAR(64, charset='ascii'), nullable=False, default='on_init')
@@ -453,6 +454,21 @@ func execITask(taskValue reflect.Value, task *STask, odata jsonutils.JSONObject,
return
}
defer func() {
if r := recover(); r != nil {
// call set stage failed, should not call task.SetStageFailed
// func SetStageFailed may be overloading
log.Errorf("Task %s PANIC on stage %s: %v \n%s", task.TaskName, stageName, r, debug.Stack())
SetStageFailedFuncValue := taskValue.MethodByName("SetStageFailed")
SetStageFailedFuncValue.Call(
[]reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(fmt.Sprintf("%v", r)),
},
)
}
}()
log.Debugf("Call %s %s %#v", task.TaskName, stageName, params)
funcValue.Call(params)
@@ -753,9 +769,8 @@ func (manager *STaskManager) QueryTasksOfObject(obj db.IStandaloneModel, since t
// subq1 and subq2 do not intersect for the fact that they have
// different condition on tasks_tbl.obj_id field
uq := sqlchemy.Union(subq1, subq2)
uq = uq.Desc("created_at")
q := uq.SubQuery().Query()
q := uq.Query().Desc("created_at")
return q
}

View File

@@ -22,11 +22,11 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
)
func Update(model IModel, updateFunc func() error) (map[string]sqlchemy.SUpdateDiff, error) {
func Update(model IModel, updateFunc func() error) (sqlchemy.UpdateDiffs, error) {
return model.GetModelManager().TableSpec().Update(model, updateFunc)
}
func UpdateWithLock(ctx context.Context, model IModel, updateFunc func() error) (map[string]sqlchemy.SUpdateDiff, error) {
func UpdateWithLock(ctx context.Context, model IModel, updateFunc func() error) (sqlchemy.UpdateDiffs, error) {
lockman.LockObject(ctx, model)
defer lockman.ReleaseObject(ctx, model)

View File

@@ -251,7 +251,11 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC
q := model.GetModelManager().Query().Equals("name", model.GetName())
q = q.Equals("tenant_id", tobj.GetId())
q = q.NotEquals("id", model.GetId())
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check name duplication error: %s", err)
}
if cnt > 0 {
return nil, httperrors.NewDuplicateNameError("name", model.GetName())
}
former, _ := TenantCacheManager.FetchTenantById(ctx, model.ProjectId)
@@ -260,7 +264,7 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC
formerObj := NewTenant(model.ProjectId, "unknown")
former = &formerObj
}
_, err := Update(model, func() error {
_, err = Update(model, func() error {
model.ProjectId = tobj.GetId()
model.ProjectSrc = string(PROJECT_SOURCE_LOCAL)
return nil
@@ -353,8 +357,12 @@ func (model *SVirtualResourceBase) MarkCancelPendingDelete(ctx context.Context,
lockman.LockClass(ctx, model.GetModelManager(), ownerProjId)
defer lockman.ReleaseClass(ctx, model.GetModelManager(), ownerProjId)
newName, err := GenerateName(model.GetModelManager(), ownerProjId, model.Name)
if err != nil {
return err
}
diff, err := Update(model, func() error {
model.Name = GenerateName(model.GetModelManager(), ownerProjId, model.Name)
model.Name = newName
model.PendingDeleted = false
model.PendingDeletedAt = time.Time{}
return nil
@@ -391,3 +399,13 @@ func (model *SVirtualResourceBase) SyncCloudProjectId(userCred mcclient.TokenCre
}
}
}
// GetPendingDeleted implements IPendingDeltable
func (model *SVirtualResourceBase) GetPendingDeleted() bool {
return model.PendingDeleted
}
// GetPendingDeletedAt implements IPendingDeltable
func (model *SVirtualResourceBase) GetPendingDeletedAt() time.Time {
return model.PendingDeletedAt
}

View File

@@ -16,16 +16,20 @@ package options
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"yunion.io/x/log"
"yunion.io/x/log/hooks"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/pkg/util/version"
"yunion.io/x/pkg/utils"
"yunion.io/x/structarg"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/util/atexit"
)
type CommonOptions struct {
@@ -34,6 +38,7 @@ type CommonOptions struct {
LogLevel string `help:"log level" default:"info" choices:"debug|info|warn|error"`
LogVerboseLevel int `help:"log verbosity level" default:"0"`
LogFilePrefix string `help:"prefix of log files"`
Region string `help:"Region name or ID" alias:"auth-region"`
AuthURL string `help:"Keystone auth URL" alias:"auth-uri"`
@@ -120,7 +125,6 @@ func ParseOptions(optStruct interface{}, args []string, configFileName string, s
if len(optionsRef.Config) == 0 {
for _, p := range []string{"./etc", "/etc/yunion"} {
confTmp := path.Join(p, configFileName)
log.Infof(confTmp)
if _, err := os.Stat(confTmp); err == nil {
optionsRef.Config = confTmp
break
@@ -148,6 +152,28 @@ func ParseOptions(optStruct interface{}, args []string, configFileName string, s
if err != nil {
log.Fatalf("Set log level %q: %v", optionsRef.LogLevel, err)
}
if optionsRef.LogFilePrefix != "" {
dir, name := filepath.Split(optionsRef.LogFilePrefix)
h := &hooks.LogFileRotateHook{
RotateNum: 10,
RotateSize: 100 * 1024 * 1024,
LogFileHook: hooks.LogFileHook{
FileDir: dir,
FileName: name,
},
}
h.Init()
log.DisableColors()
log.Logger().AddHook(h)
log.Logger().Out = ioutil.Discard
atexit.Register(atexit.ExitHandler{
Prio: atexit.PRIO_LOG_CLOSE,
Reason: "deinit log rotate hook",
Func: func(atexit.ExitHandler) {
h.DeInit()
},
})
}
log.V(10).Debugf("Parsed options: %#v", optStruct)

View File

@@ -14,4 +14,67 @@
package service
type SServiceBase struct{}
import (
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"yunion.io/x/onecloud/pkg/cloudcommon/options"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/procutils"
)
type IService interface {
InitService()
RunService()
OnExitService()
}
type SServiceBase struct {
Service IService
O *options.CommonOptions
}
func (s *SServiceBase) StartService() {
defer s.Service.OnExitService()
defer s.RemovePid()
s.Service.InitService()
if err := s.CreatePid(); err != nil {
log.Fatalln(err)
}
s.Service.RunService()
}
func (s *SServiceBase) CreatePid() error {
if s.O == nil || len(s.O.PidFile) == 0 {
return nil
}
absPath, err := filepath.Abs(s.O.PidFile)
if err != nil {
return fmt.Errorf("Get pidfile %s absolute path failed: %s", s.O.PidFile, err)
}
s.O.PidFile = absPath
pidDir := filepath.Dir(s.O.PidFile)
if !fileutils2.Exists(pidDir) {
output, err := procutils.NewCommand("mkdir", "-p", pidDir).Run()
if err != nil {
return fmt.Errorf("Make pid dir %s failed: %s", pidDir, output)
}
}
err = fileutils2.FilePutContents(s.O.PidFile, strconv.Itoa(os.Getpid()), false)
if err != nil {
return fmt.Errorf("Write pidfile %s failed: %s", s.O.PidFile, err)
}
return nil
}
func (s *SServiceBase) RemovePid() {
if s.O != nil && len(s.O.PidFile) > 0 && fileutils2.Exists(s.O.PidFile) {
os.Remove(s.O.PidFile)
}
}

View File

@@ -39,10 +39,11 @@ func (info *SDMISystemInfo) ToIPMISystemInfo() *SIPMISystemInfo {
}
type SCPUInfo struct {
Count int `json:"count"`
Model string `json:"desc"`
Freq int `json:"freq"`
Cache int `json:"cache"`
Count int `json:"count"`
Model string `json:"desc"`
Freq int `json:"freq"`
Cache int `json:"cache"`
Microcode string `json:"microcode"`
}
type SDMICPUInfo struct {

View File

@@ -98,7 +98,7 @@ func newInvalidStructError(key string, err error) error {
params := []interface{}{key}
jsonClientErr, ok := err.(*httputils.JSONClientError)
if ok {
errFmt += jsonClientErr.Data.Id
errFmt += httperrors.MsgTmplToFmt(jsonClientErr.Data.Id)
for _, f := range jsonClientErr.Data.Fields {
params = append(params, f)
}
@@ -113,7 +113,7 @@ func newModelManagerError(modelKeyword string) error {
func newModelNotFoundError(modelKeyword, idOrName string, err error) error {
errFmt := "cannot find %q with id/name %q"
params := []interface{}{modelKeyword, idOrName}
if err != sql.ErrNoRows {
if err != nil && err != sql.ErrNoRows {
errFmt += ": %s"
params = append(params, err.Error())
}

View File

@@ -375,12 +375,13 @@ func NewNonNegativeValidator(key string) *ValidatorRange {
type ValidatorModelIdOrName struct {
Validator
ModelKeyword string
ProjectId string
UserId string
ModelManager db.IModelManager
Model db.IModel
modelIdKey string
ModelKeyword string
ProjectId string
UserId string
ModelManager db.IModelManager
Model db.IModel
modelIdKey string
noPendingDeleted bool
}
func (v *ValidatorModelIdOrName) GetProjectId() string {
@@ -401,10 +402,11 @@ func (v *ValidatorModelIdOrName) getValue() interface{} {
func NewModelIdOrNameValidator(key string, modelKeyword string, projectId string) *ValidatorModelIdOrName {
v := &ValidatorModelIdOrName{
Validator: Validator{Key: key},
ProjectId: projectId,
ModelKeyword: modelKeyword,
modelIdKey: key + "_id",
Validator: Validator{Key: key},
ProjectId: projectId,
ModelKeyword: modelKeyword,
modelIdKey: key + "_id",
noPendingDeleted: true,
}
v.parent = v
return v
@@ -415,6 +417,12 @@ func (v *ValidatorModelIdOrName) ModelIdKey(modelIdKey string) *ValidatorModelId
return v
}
// AllowPendingDeleted allows the to-be-validated id or name to be of a pending deleted model
func (v *ValidatorModelIdOrName) AllowPendingDeleted(b bool) *ValidatorModelIdOrName {
v.noPendingDeleted = !b
return v
}
func (v *ValidatorModelIdOrName) validate(data *jsonutils.JSONDict) error {
if err, isSet := v.Validator.validateEx(data); err != nil || !isSet {
return err
@@ -433,6 +441,11 @@ func (v *ValidatorModelIdOrName) validate(data *jsonutils.JSONDict) error {
if err != nil {
return newModelNotFoundError(v.ModelKeyword, modelIdOrName, err)
}
if v.noPendingDeleted {
if pd, ok := model.(db.IPendingDeletable); ok && pd.GetPendingDeleted() {
return newModelNotFoundError(v.ModelKeyword, modelIdOrName, nil)
}
}
v.Model = model
return nil
}

View File

@@ -34,3 +34,4 @@ var ErrTimeout = errors.New("timeout")
var ErrNotImplemented = errors.New("Not implemented")
var ErrNotSupported = errors.New("Not supported")
var ErrInvalidProvider = errors.New("Invalid provider")
var ErrNoBalancePermission = errors.New("No balance permission")

View File

@@ -71,3 +71,14 @@ func CloudImage2Image(image ICloudImage) SImage {
Status: image.GetImageStatus(),
}
}
type SImageCreateOption struct {
ImageId string
ExternalId string
ImageName string
OsType string
OsArch string
OsDistribution string
OsVersion string
OsFullVersion string
}

View File

@@ -15,6 +15,8 @@
package cloudprovider
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/osprofile"
@@ -53,9 +55,9 @@ type SManagedVMCreateConfig struct {
PublicKey string
ExternalSecgroupId string
ExternalSecgroupIds []string
Account string
Password string
UserData string
UserDataType string
BillingCycle *billing.SBillingCycle
}
@@ -69,15 +71,11 @@ func (vmConfig *SManagedVMCreateConfig) GetConfig(config *jsonutils.JSONDict) er
}
//目前所写的userData格式仅支持Linux
if vmConfig.OsType == osprofile.OS_TYPE_LINUX {
if userDataType, _ := config.GetString("user_data_type"); len(userDataType) > 0 {
vmConfig.UserDataType = userDataType
}
adminPublicKey, _ := config.GetString("admin_public_key")
projectPublicKey, _ := config.GetString("project_public_key")
oUserData, _ := config.GetString("user_data")
vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, oUserData, vmConfig.UserDataType)
vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, oUserData)
}
resetPassword := jsonutils.QueryBoolean(config, "reset_password", false)
@@ -88,11 +86,11 @@ func (vmConfig *SManagedVMCreateConfig) GetConfig(config *jsonutils.JSONDict) er
return nil
}
func generateUserData(adminPublicKey, projectPublicKey, oUserData string, userDataType string) string {
func generateUserData(adminPublicKey, projectPublicKey, oUserData string) string {
var oCloudConfig *cloudinit.SCloudConfig
if len(oUserData) > 0 {
oCloudConfig, _ = cloudinit.ParseUserDataBase64(oUserData)
oCloudConfig, _ = cloudinit.ParseUserData(oUserData)
}
ansibleUser := cloudinit.NewUser(ansible.PUBLIC_CLOUD_ANSIBLE_USER)
@@ -111,9 +109,37 @@ func generateUserData(adminPublicKey, projectPublicKey, oUserData string, userDa
cloudConfig.Merge(oCloudConfig)
}
if userDataType == CLOUD_SHELL {
return cloudConfig.UserDataScriptBase64()
return cloudConfig.UserData()
}
func (vmConfig *SManagedVMCreateConfig) InjectPasswordByCloudInit() error {
if vmConfig.OsType != osprofile.OS_TYPE_LINUX {
return fmt.Errorf("Only support inject Linux password, current osType is %s", vmConfig.OsType)
}
loginUser := cloudinit.NewUser(vmConfig.Account)
loginUser.SudoPolicy(cloudinit.USER_SUDO_NOPASSWD)
if len(vmConfig.PublicKey) > 0 {
loginUser.SshKey(vmConfig.PublicKey)
}
if len(vmConfig.Password) > 0 {
loginUser.Password(vmConfig.Password)
}
return cloudConfig.UserDataBase64()
cloudconfig := cloudinit.SCloudConfig{
DisableRoot: 0,
SshPwauth: 1,
Users: []cloudinit.SUser{
loginUser,
},
}
if len(vmConfig.UserData) > 0 {
oCloudConfig, err := cloudinit.ParseUserData(vmConfig.UserData)
if err != nil {
return err
}
cloudconfig.Merge(oCloudConfig)
}
vmConfig.UserData = cloudconfig.UserData()
return nil
}

View File

@@ -31,6 +31,9 @@ type SLoadbalancerListener struct {
Description string
EstablishedTimeout int
HealthCheckReq string
HealthCheckExp string
HealthCheck string
HealthCheckTimeout int
HealthCheckDomain string

View File

@@ -45,6 +45,7 @@ type IVirtualResource interface {
type IBillingResource interface {
GetBillingType() string
GetCreatedAt() time.Time
GetExpiredAt() time.Time
}
@@ -136,13 +137,11 @@ type ICloudStoragecache interface {
GetPath() string
GetManagerId() string
CreateIImage(snapshotId, imageName, osType, imageDesc string) (ICloudImage, error)
DownloadImage(userCred mcclient.TokenCredential, imageId string, extId string, path string) (jsonutils.JSONObject, error)
UploadImage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist, osVersion string, extId string, isForce bool) (string, error)
UploadImage(ctx context.Context, userCred mcclient.TokenCredential, image *SImageCreateOption, isForce bool) (string, error)
}
type ICloudStorage interface {
@@ -159,8 +158,6 @@ type ICloudStorage interface {
GetStorageConf() jsonutils.JSONObject
GetEnabled() bool
GetManagerId() string
CreateIDisk(name string, sizeGb int, desc string) (ICloudDisk, error)
GetIDiskById(idStr string) (ICloudDisk, error)
@@ -199,8 +196,6 @@ type ICloudHost interface {
GetIsMaintenance() bool
GetVersion() string
GetManagerId() string
CreateVM(desc *SManagedVMCreateConfig) (ICloudVM, error)
GetIHostNics() ([]ICloudHostNetInterface, error)
}
@@ -287,8 +282,6 @@ type ICloudEIP interface {
GetInternetChargeType() string
GetManagerId() string
Delete() error
Associate(instanceId string) error
@@ -308,7 +301,6 @@ type ICloudSecurityGroup interface {
type ICloudRouteTable interface {
ICloudResource
GetManagerId() string
GetDescription() string
GetRegionId() string
@@ -362,7 +354,7 @@ type ICloudSnapshot interface {
ICloudResource
IVirtualResource
GetSize() int32
GetSizeMb() int32
GetDiskId() string
GetDiskType() string
Delete() error
@@ -379,8 +371,6 @@ type ICloudVpc interface {
GetISecurityGroups() ([]ICloudSecurityGroup, error)
GetIRouteTables() ([]ICloudRouteTable, error)
GetManagerId() string
Delete() error
GetIWireById(wireId string) (ICloudWire, error)
@@ -526,6 +516,7 @@ type ICloudLoadbalancerBackendGroup interface {
IsDefault() bool
GetType() string
GetILoadbalancerBackends() ([]ICloudLoadbalancerBackend, error)
GetILoadbalancerBackendById(backendId string) (ICloudLoadbalancerBackend, error)
AddBackendServer(serverId string, weight int, port int) (ICloudLoadbalancerBackend, error)
RemoveBackendServer(serverId string, weight int, port int) error
@@ -542,6 +533,7 @@ type ICloudLoadbalancerBackend interface {
GetBackendType() string
GetBackendRole() string
GetBackendId() string
SyncConf(port, weight int) error
}
type ICloudLoadbalancerCertificate interface {

View File

@@ -82,8 +82,18 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal
selected = make([]*BaremetalStorage, 0)
rest = make([]*BaremetalStorage, 0)
idx := 0
curAdapter := 0
adapterChange := false
for _, storage := range storages {
if storage.Adapter != curAdapter {
adapterChange = true
curAdapter = storage.Adapter
}
if adapterChange {
idx = 0
adapterChange = false
}
if storage.Index == 0 {
storage.Index = int64(idx)
}
@@ -535,10 +545,11 @@ func GetDiskSpecV2(storages []*BaremetalStorage) api.DiskDriverSpec {
}
type DiskConfiguration struct {
Driver string
Adapter int
Block int64
Size int64
Driver string
Adapter int
RaidConfig string
Block int64
Size int64
}
func GetDiskConfigurations(layouts []Layout) []DiskConfiguration {
@@ -550,15 +561,33 @@ func GetDiskConfigurations(layouts []Layout) []DiskConfiguration {
raidConf := rr.Conf.Conf
if raidConf == DISK_CONF_NONE {
for _, d := range rr.Disks {
disks = append(disks, DiskConfiguration{Driver: driver, Adapter: adapter, Block: block, Size: d.Size})
disks = append(disks, DiskConfiguration{
Driver: driver,
Adapter: adapter,
RaidConfig: raidConf,
Block: block,
Size: d.Size,
})
}
} else {
if len(rr.Conf.Size) != 0 {
for _, sz := range rr.Conf.Size {
disks = append(disks, DiskConfiguration{Driver: driver, Adapter: adapter, Block: block, Size: sz})
disks = append(disks, DiskConfiguration{
Driver: driver,
Adapter: adapter,
RaidConfig: raidConf,
Block: block,
Size: sz,
})
}
} else {
disks = append(disks, DiskConfiguration{Driver: driver, Adapter: adapter, Block: block, Size: rr.Size})
disks = append(disks, DiskConfiguration{
Driver: driver,
Adapter: adapter,
RaidConfig: raidConf,
Block: block,
Size: rr.Size,
})
}
}
}
@@ -592,3 +621,36 @@ func GroupLayoutResultsByDriverAdapter(layouts []Layout) []*DriverAdapterDiskCon
}
return ret
}
func ValidateDiskConfigs(confs []*api.BaremetalDiskConfig) error {
if len(confs) == 0 {
return nil
}
for idx, conf := range confs {
if conf.Conf != DISK_CONF_NONE {
// raid validate
if idx > 0 {
preConf := confs[idx-1]
if preConf.Conf == DISK_CONF_NONE {
return fmt.Errorf("Raid config %d must before none raid config", idx)
}
}
} else {
// none raid validate
if idx+1 == len(confs) {
return nil
}
restConfs := confs[idx+1:]
hasRaidConf := false
for _, restConf := range restConfs {
if restConf.Conf != DISK_CONF_NONE {
hasRaidConf = true
}
}
if hasRaidConf {
return fmt.Errorf("Raid config after none raid config %d", idx)
}
}
}
return nil
}

View File

@@ -19,7 +19,6 @@ import (
"reflect"
"testing"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
)
@@ -203,7 +202,7 @@ var (
Adapter: 2,
},
// 12-13 disk on adapter0
// 0-1 disk on adapter0
{
Driver: DISK_DRIVER_MEGARAID,
Rotate: true,
@@ -295,7 +294,7 @@ var (
func TestCalculateLayout(t *testing.T) {
confs, err := NewBaremetalDiskConfigs(
"[12-13]:raid1:(100g,32g,):adapter0",
"[0-1]:raid1:(100g,32g,):adapter0",
"6:raid5:adapter2",
"6:raid5:adapter2",
)
@@ -311,13 +310,13 @@ func TestCalculateLayout(t *testing.T) {
"rotate": true,
"driver": "MegaRaid",
"size": 953344,
"index": 12
"index": 0
},
{
"rotate": true,
"driver": "MegaRaid",
"size": 953344,
"index": 13
"index": 1
}
],
"conf": {
@@ -325,8 +324,8 @@ func TestCalculateLayout(t *testing.T) {
"conf": "raid1",
"count": 0,
"range": [
12,
13
0,
1
],
"splits": "100g,32g,",
"size": [
@@ -472,7 +471,7 @@ func TestCalculateLayout(t *testing.T) {
func TestCheckDisksAllocable(t *testing.T) {
confs, err := NewBaremetalDiskConfigs(
"[12-13]:raid1:(100g,32g,):adapter0",
"[0-1]:raid1:(100g,32g,):adapter0",
"6:raid5:adapter2",
"6:raid5:adapter2",
)
@@ -491,10 +490,6 @@ func TestCheckDisksAllocable(t *testing.T) {
t.Fatalf("Calculate bitmain layout err: %v", err)
}
log.Debugf("defaultLayout: %s", defaultLayout)
log.Debugf("layout: %s", layout)
log.Debugf("Bitmain layout: %s", bitmainLayout)
tdiskDefault := []*Disk{
{Size: -1},
{Size: -1},
@@ -949,11 +944,10 @@ func TestStorageLoad(t *testing.T) {
t.Fatalf("NewDiskConfigs err: %v", err)
}
json.Unmarshal([]byte(testStorages2), &ss)
layout, err := CalculateLayout(confs, ss)
_, err = CalculateLayout(confs, ss)
if err != nil {
t.Fatalf("CalculateLayout err: %v", err)
}
log.Debugf("layout: %s", layout)
}
func TestCalculateSize(t *testing.T) {
@@ -1076,3 +1070,179 @@ func TestGetDiskSpecs(t *testing.T) {
})
}
}
func TestValidateDiskConfigs(t *testing.T) {
tests := []struct {
name string
confs []*api.BaremetalDiskConfig
wantErr bool
}{
{
name: "empty",
confs: []*api.BaremetalDiskConfig{},
wantErr: false,
},
{
name: "none_raid",
confs: []*api.BaremetalDiskConfig{
{Conf: DISK_CONF_NONE},
{Conf: DISK_CONF_RAID0},
},
wantErr: true,
},
{
name: "raid_none_raid",
confs: []*api.BaremetalDiskConfig{
{Conf: DISK_CONF_RAID0},
{Conf: DISK_CONF_NONE},
{Conf: DISK_CONF_RAID5},
},
wantErr: true,
},
{
name: "nones",
confs: []*api.BaremetalDiskConfig{
{Conf: DISK_CONF_NONE},
{Conf: DISK_CONF_NONE},
},
wantErr: false,
},
{
name: "raids_nones",
confs: []*api.BaremetalDiskConfig{
{Conf: DISK_CONF_RAID0},
{Conf: DISK_CONF_RAID5},
{Conf: DISK_CONF_NONE},
{Conf: DISK_CONF_NONE},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := ValidateDiskConfigs(tt.confs); (err != nil) != tt.wantErr {
t.Errorf("ValidateDiskConfigs() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestRetrieveStorages(t *testing.T) {
type args struct {
diskConfig *api.BaremetalDiskConfig
storages []*BaremetalStorage
}
s1 := &BaremetalStorage{
Size: 1,
Driver: "MegaRaid",
Adapter: 0,
}
s2 := &BaremetalStorage{
Size: 1,
Driver: "MegaRaid",
Adapter: 0,
}
s3 := &BaremetalStorage{
Size: 2,
Driver: "MegaRaid",
Adapter: 0,
}
tests := []struct {
name string
args args
wantSelected []*BaremetalStorage
wantRest []*BaremetalStorage
}{
{
name: "select all",
args: args{
diskConfig: &api.BaremetalDiskConfig{
Driver: "MegaRaid",
Count: 0,
Type: api.DISK_TYPE_HYBRID,
},
storages: []*BaremetalStorage{s1, s2, s3},
},
wantSelected: []*BaremetalStorage{s1, s2, s3},
wantRest: []*BaremetalStorage{},
},
{
name: "select count 2",
args: args{
diskConfig: &api.BaremetalDiskConfig{
Driver: "MegaRaid",
Count: 2,
Type: api.DISK_TYPE_HYBRID,
},
storages: []*BaremetalStorage{s1, s2, s3},
},
wantSelected: []*BaremetalStorage{s1, s2},
wantRest: []*BaremetalStorage{s3},
},
{
name: "select by range",
args: args{
diskConfig: &api.BaremetalDiskConfig{
Driver: "MegaRaid",
Range: []int64{1, 2},
Type: api.DISK_TYPE_HYBRID,
},
storages: []*BaremetalStorage{s1, s2, s3},
},
wantSelected: []*BaremetalStorage{s2, s3},
wantRest: []*BaremetalStorage{s1},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotSelected, gotRest := RetrieveStorages(tt.args.diskConfig, tt.args.storages)
if !reflect.DeepEqual(gotSelected, tt.wantSelected) {
t.Errorf("RetrieveStorages() gotSelected = %v, want %v", gotSelected, tt.wantSelected)
}
if !reflect.DeepEqual(gotRest, tt.wantRest) {
t.Errorf("RetrieveStorages() gotRest = %v, want %v", gotRest, tt.wantRest)
}
})
}
}
func TestGetSplitSizes(t *testing.T) {
type args struct {
size int64
splitConf string
}
var totalSize int64 = 22889472
size10p := int64(float64(totalSize) * 0.1)
tests := []struct {
name string
args args
want []int64
}{
{
name: "split gb",
args: args{
size: totalSize,
splitConf: "60g,",
},
want: []int64{61440, totalSize - 61440},
},
{
name: "split by percent",
args: args{
size: totalSize,
splitConf: "10%,",
},
want: []int64{
size10p,
totalSize - size10p,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetSplitSizes(tt.args.size, tt.args.splitConf); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetSplitSizes() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -42,6 +42,10 @@ func (self *SAliyunGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_ALIYUN
}
func (self *SAliyunGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ALIYUN
}
func (self *SAliyunGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_CLOUD_EFFICIENCY
}
@@ -128,6 +132,9 @@ func (self *SAliyunGuestDriver) ValidateCreateData(ctx context.Context, userCred
}
}
}
if input.EipBw > 100 {
return nil, httperrors.NewInputParameterError("%s requires that the eip bandwidth must be less than 100Mbps", self.GetHypervisor())
}
return input, nil
}
@@ -147,160 +154,6 @@ func (self *SAliyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManag
return userName
}
/* func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
userName := "root"
if desc.ImageType == "system" && desc.OsType == "Windows" {
userName = "Administrator"
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status ready ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 || idisks[0].GetGlobalId() != diskId {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
if len(idisks) < len(desc.DataDisks)+1 {
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
}
if len(idisks) > 0 && idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
}
time.Sleep(time.Second * 5)
waited += 5
} else {
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else {
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
} */
func (self *SAliyunGuestDriver) AllowReconfigGuest() bool {
return true
}

View File

@@ -67,6 +67,10 @@ func fetchAwsUserName(desc cloudprovider.SManagedVMCreateConfig) string {
}
}
func (self *SAwsGuestDriver) IsNeedInjectPasswordByCloudInit(desc *cloudprovider.SManagedVMCreateConfig) bool {
return true
}
func (self *SAwsGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
// return fetchAwsUserName(desc)
return api.VM_AWS_DEFAULT_LOGIN_USER
@@ -76,6 +80,10 @@ func (self *SAwsGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_AWS
}
func (self *SAwsGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_AWS
}
func (self *SAwsGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_GP2_SSD
}
@@ -148,137 +156,6 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
/*func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
username := fetchAwsUserName(desc)
switch action {
case "create":
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
case "deploy":
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
case "rebuild":
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
time.Sleep(time.Second * 5)
waited += 5
} else {
if idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
return nil, fmt.Errorf("inconsistent sys disk id after rebuild root")
}
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
default:
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
}*/
func (self *SAwsGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
return false
}

View File

@@ -20,18 +20,15 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/cmdline"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/ansible"
"yunion.io/x/onecloud/pkg/util/billing"
)
@@ -48,6 +45,10 @@ func (self *SAzureGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_AZURE
}
func (self *SAzureGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_AZURE
}
func (self *SAzureGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_STANDARD_LRS
}
@@ -125,10 +126,6 @@ func (self *SAzureGuestDriver) ValidateUpdateData(ctx context.Context, userCred
if err != nil {
return nil, err
}
input, err = self.SManagedVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, input)
if err != nil {
return nil, err
}
if input.Name != "" {
return nil, httperrors.NewInputParameterError("cannot support change azure instance name")
}
@@ -144,166 +141,15 @@ func (self *SAzureGuestDriver) GetGuestInitialStateAfterRebuild() string {
}
func (self *SAzureGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
return ansible.PUBLIC_CLOUD_ANSIBLE_USER
return api.VM_AZURE_DEFAULT_LOGIN_USER
}
/* func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
func (self *SAzureGuestDriver) GetGuestSecgroupVpcid(guest *models.SGuest) (string, error) {
host := guest.GetHost()
if host != nil && strings.HasSuffix(host.Name, "-classic") {
return "classic", nil
}
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.Password) == 0 {
//Azure创建必须要设置密码
desc.Password = seclib2.RandomPassword2(12)
}
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
if err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800); err != nil {
return nil, err
}
if iVM, err = ihost.GetIVMById(iVM.GetGlobalId()); err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else {
return fmt.Errorf("Action %s not supported", action)
}
return nil
} */
func (self *SAzureGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
}
iVM, err := ihost.GetIVMById(guest.ExternalId)
if err != nil {
return nil, err
}
if fwOnly, _ := task.GetParams().Bool("fw_only"); fwOnly {
vpcID := "normal"
if strings.HasSuffix(host.Name, "-classic") {
vpcID = "classic"
}
iregion, err := host.GetIRegion()
if err != nil {
return nil, err
}
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcID))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcID))
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), guest.SecgrpId, vpcID, host.GetRegion().Id, host.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s", guest.SecgrpId, vpcID)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcID, guest.GetSecgroupName(), "", guest.GetSecRules())
if err != nil {
return nil, err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return nil, err
}
return nil, iVM.AssignSecurityGroup(extID)
}
iDisks, err := iVM.GetIDisks()
if err != nil {
return nil, err
}
disks := make([]models.SDisk, 0)
for _, guestdisk := range guest.GetDisks() {
disk := guestdisk.GetDisk()
disks = append(disks, *disk)
}
added := make([]models.SDisk, 0)
commondb := make([]models.SDisk, 0)
commonext := make([]cloudprovider.ICloudDisk, 0)
removed := make([]cloudprovider.ICloudDisk, 0)
if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil {
return nil, err
}
for _, disk := range removed {
if err := iVM.DetachDisk(ctx, disk.GetId()); err != nil {
return nil, err
}
}
for _, disk := range added {
if err := iVM.AttachDisk(ctx, disk.ExternalId); err != nil {
return nil, err
}
}
return nil, nil
})
return nil
return api.NORMAL_VPC_ID, nil
}
func (self *SAzureGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {

View File

@@ -49,6 +49,10 @@ func (self *SBaremetalGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_BAREMETAL
}
func (self *SBaremetalGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ONECLOUD
}
func (self *SBaremetalGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_LOCAL
}
@@ -312,23 +316,11 @@ func (self *SBaremetalGuestDriver) StartGuestSyncstatusTask(guest *models.SGuest
}
func (self *SBaremetalGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
/*var confs = make([]api.BaremetalDiskConfig, 0)*/
//jsonArray := jsonutils.GetArrayOfPrefix(data, "baremetal_disk_config")
//for i := 0; i < len(jsonArray); i += 1 {
//// for data.Contains(fmt.Sprintf("baremetal_disk_config.%d", len(confs))) {
//desc, _ := jsonArray[i].GetString() // data.GetString(fmt.Sprintf("baremetal_disk_config.%d", len(confs)))
//data.Remove(fmt.Sprintf("baremetal_disk_config.%d", i))
//bmConf, err := baremetal.ParseDiskConfig(desc)
//if err != nil {
//return nil, httperrors.NewInputParameterError("baremetal_disk_config.%d", i)
//}
//confs = append(confs, bmConf)
//}
//if len(confs) == 0 {
//bmConf, _ := baremetal.ParseDiskConfig("")
//confs = append(confs, bmConf)
//}
/*data.Set("baremetal_disk_config", jsonutils.Marshal(confs))*/
if len(input.BaremetalDiskConfigs) != 0 {
if err := baremetal.ValidateDiskConfigs(input.BaremetalDiskConfigs); err != nil {
return nil, httperrors.NewInputParameterError("Invalid raid config: %v", err)
}
}
if len(input.Disks) <= 0 {
return nil, httperrors.NewInputParameterError("Root disk must be present")
}
@@ -377,11 +369,6 @@ func (self *SBaremetalGuestDriver) CheckDiskTemplateOnStorage(ctx context.Contex
return nil
}
func (self *SBaremetalGuestDriver) OnGuestDeployTaskComplete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
task.SetStage("OnDeployGuestSyncstatusComplete", nil)
return guest.StartSyncstatus(ctx, task.GetUserCred(), task.GetTaskId())
}
func (self *SBaremetalGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Context, guest *models.SGuest, task taskman.ITask, data jsonutils.JSONObject) error {
if data.Contains("disks") {
disks, _ := data.GetArray("disks")

Some files were not shown because too many files have changed in this diff Show More