mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-21 00:24:07 +08:00
Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd93784606 | ||
|
|
aebe35a853 | ||
|
|
39a944d5d5 | ||
|
|
dc2e87a74f | ||
|
|
c3d0b0fe1f | ||
|
|
adff20026e | ||
|
|
d1318d10e3 | ||
|
|
92ac613717 | ||
|
|
243953ba6a | ||
|
|
1dc421a6db | ||
|
|
64e1116b32 | ||
|
|
c8073bdd75 | ||
|
|
da585a7b35 | ||
|
|
da0a7c7b6e | ||
|
|
37aa862950 | ||
|
|
e55220cd11 | ||
|
|
9dfb23c281 | ||
|
|
8504d364ff | ||
|
|
6aebdcec1f | ||
|
|
aa539bff9e | ||
|
|
4a59e25772 | ||
|
|
f68601d1b9 | ||
|
|
2eeecf9e68 | ||
|
|
75a007ea19 | ||
|
|
f3ae127f2c | ||
|
|
b95b553b9b | ||
|
|
7d1f968044 | ||
|
|
7ce8ef8ab0 | ||
|
|
7c90d219b3 | ||
|
|
91141d6432 | ||
|
|
0e5459c669 | ||
|
|
fc61c093e3 | ||
|
|
b595f59ef8 | ||
|
|
07292089fa | ||
|
|
df79388ded | ||
|
|
c84dd96fff | ||
|
|
cfef1fe2a3 | ||
|
|
46517ebd13 | ||
|
|
7093cd6db2 | ||
|
|
71f0b9e2df | ||
|
|
aca33fe970 | ||
|
|
906a591f00 | ||
|
|
38f3dceeb1 | ||
|
|
c0ba43e5f1 | ||
|
|
b281cf7137 | ||
|
|
a11c14dfce | ||
|
|
0e15b63b78 | ||
|
|
824fc247a7 | ||
|
|
e1c1c0b842 | ||
|
|
3adae60e23 | ||
|
|
62b78fd43c | ||
|
|
09f44d79a4 | ||
|
|
e82392107f | ||
|
|
ed676427d2 | ||
|
|
e13885e22b | ||
|
|
bc159c7c55 | ||
|
|
bf19d87ed1 | ||
|
|
9464fbe6b2 | ||
|
|
de811130ca | ||
|
|
951e9218ce | ||
|
|
d79741dc21 | ||
|
|
d43e645ed2 | ||
|
|
170b373740 | ||
|
|
4eaa4ee9d3 | ||
|
|
2ca8d0f7e4 | ||
|
|
2ee3b2c8ab | ||
|
|
e1b2e2b508 | ||
|
|
eb4b22eaec | ||
|
|
42ec59e811 | ||
|
|
a14ab9820d | ||
|
|
94d2bc456d | ||
|
|
5cd48cec5f | ||
|
|
c039a56be1 | ||
|
|
c24235c137 | ||
|
|
85f85e394d | ||
|
|
5fdde01bea | ||
|
|
59e1534222 | ||
|
|
f6da9ad66a | ||
|
|
b55c2f7d21 | ||
|
|
24e29349bf | ||
|
|
aa7c5f1b1a | ||
|
|
a3b1b99cc4 | ||
|
|
899afd7065 | ||
|
|
2bf31dbd3a | ||
|
|
35d8cba97f | ||
|
|
8a1be0852d | ||
|
|
ef29136266 | ||
|
|
adaa7fa2ce | ||
|
|
62a4bce191 | ||
|
|
1ecbb46e59 | ||
|
|
58ca8180b6 | ||
|
|
08819e2201 | ||
|
|
b4f5f1a996 | ||
|
|
85f6e95c18 | ||
|
|
8a71e73afd | ||
|
|
407f155df1 | ||
|
|
ab0c6f1284 | ||
|
|
99d1137805 | ||
|
|
95a03ad58b | ||
|
|
659022c792 | ||
|
|
b55ac81e2a | ||
|
|
bd69dc44d7 | ||
|
|
06c303c648 | ||
|
|
15fbc035ab | ||
|
|
a25de48df9 | ||
|
|
be065e872d | ||
|
|
4c27add0ba | ||
|
|
d238540dcb | ||
|
|
fdd0bf77e6 | ||
|
|
ab5fcdad3d | ||
|
|
38d23b0739 | ||
|
|
b45811166b | ||
|
|
2ee1af186d | ||
|
|
14e537fc65 | ||
|
|
f3e503e8a6 | ||
|
|
10ad815d6d | ||
|
|
01a17c952d | ||
|
|
dcb8898c06 | ||
|
|
d7ff1314e6 | ||
|
|
d6a0764b29 | ||
|
|
e841a42143 | ||
|
|
c55d5d0cf2 | ||
|
|
76df031884 | ||
|
|
f46dfc6d6a | ||
|
|
1fc2503812 | ||
|
|
aa9ad9fe00 | ||
|
|
4cf674992c | ||
|
|
5565bb3064 | ||
|
|
aede49450e | ||
|
|
c7efbc3124 | ||
|
|
d090d76f92 | ||
|
|
1333d39c60 | ||
|
|
615cb1e331 | ||
|
|
923e8ea742 | ||
|
|
50b50d57dc | ||
|
|
67a4893534 | ||
|
|
e6d8dbe4a4 | ||
|
|
6c3c2f76c2 | ||
|
|
a5cd56f3d7 | ||
|
|
d691775beb | ||
|
|
73cda1d909 | ||
|
|
0c904591c0 | ||
|
|
5e8549b30f | ||
|
|
1c1fab0ef6 | ||
|
|
88d1f93e31 | ||
|
|
65748b374c | ||
|
|
4c83b1af48 | ||
|
|
f29d07dbd4 | ||
|
|
420e912c65 | ||
|
|
35d15a23c6 | ||
|
|
44ed684930 | ||
|
|
2889279284 | ||
|
|
1b1cccab94 | ||
|
|
5261b52b84 | ||
|
|
6068ea04a2 | ||
|
|
d7380f3ecc | ||
|
|
01eeff06a1 | ||
|
|
45d219ac51 | ||
|
|
8cc8d101b5 | ||
|
|
2df45f0a3c | ||
|
|
d397ac8608 | ||
|
|
71171ed0d9 | ||
|
|
c399153f14 | ||
|
|
2f7ee9fc79 | ||
|
|
630284c2ae | ||
|
|
b1a4507325 | ||
|
|
5b21958587 | ||
|
|
be71185b17 | ||
|
|
5981783ea4 | ||
|
|
04f4d036cf | ||
|
|
c615675ad9 | ||
|
|
4735edff60 | ||
|
|
4e099b72ad | ||
|
|
14bd5def5d | ||
|
|
0ee42cffea | ||
|
|
08b74642f8 |
18
Makefile
18
Makefile
@@ -89,6 +89,9 @@ vet:
|
||||
cmd/esxi-agent: prepare_dir
|
||||
CGO_ENABLED=0 $(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
cmd/fetcherfs: prepare_dir
|
||||
CGO_ENABLED=0 $(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
cmd/%: prepare_dir
|
||||
$(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
@@ -101,6 +104,21 @@ deb/%: cmd/%
|
||||
pkg/%: prepare_dir
|
||||
$(GO_INSTALL) $(REPO_PREFIX)/$@
|
||||
|
||||
rpm/fetcherfs: cmd/fetcherfs
|
||||
docker run --rm \
|
||||
--name docker-centos-build-fetcherfs \
|
||||
-v $(CURDIR):/data \
|
||||
registry.cn-beijing.aliyuncs.com/yunionio/centos-build:1.1-4 \
|
||||
/bin/bash -c "VERSION=3.6 /data/build/build.sh fetcherfs /opt/yunion/fetchclient/bin"
|
||||
|
||||
deb/fetcherfs: rpm/fetcherfs
|
||||
#VERSION=3.6 $(DEB_BUILD_SCRIPT) fetcherfs /opt/yunion/fetchclient/bin
|
||||
docker run --rm \
|
||||
--name docker-debian-build-fetcherfs \
|
||||
-v $(CURDIR):/data \
|
||||
registry.cn-beijing.aliyuncs.com/yunionio/debian10-base:1.0 \
|
||||
/data/build/convert_rpm2deb.sh
|
||||
|
||||
build:
|
||||
$(MAKE) $(cmdTargets)
|
||||
|
||||
|
||||
18
README-CN.md
18
README-CN.md
@@ -1,12 +1,12 @@
|
||||
# Yunion OneCloud (云联融合云)
|
||||
# Yunion Cloud (云联融合云)
|
||||
|
||||
[](https://circleci.com/gh/yunionio/onecloud)
|
||||
[](https://travis-ci.org/yunionio/onecloud)
|
||||
[](https://goreportcard.com/report/github.com/yunionio/onecloud)
|
||||
[](https://circleci.com/gh/yunionio/yunioncloud)
|
||||
[](https://travis-ci.org/yunionio/yunioncloud)
|
||||
[](https://goreportcard.com/report/github.com/yunionio/yunioncloud)
|
||||
|
||||
## 什么是云联融合云?
|
||||
|
||||
云联融合云(Yunion OneCloud)是一个开源的多云平台。融合云构建在用户分布于多云基础设施之上,通过技术手段将分布于多云的异构IT资源统一管理,将多底层多云的差异向用户屏蔽,并通过网络和调度实现资源的融合与打通,在多云之上进行抽象,向用户呈现统一的使用界面和API接口,让用户就像使用一个云平台一样使用分布于多云的资源,实现一个统一的“云上之云”的云平台。
|
||||
云联融合云(Yunion Cloud)是一个开源的多云平台。融合云构建在用户分布于多云基础设施之上,通过技术手段将分布于多云的异构IT资源统一管理,将多底层多云的差异向用户屏蔽,并通过网络和调度实现资源的融合与打通,在多云之上进行抽象,向用户呈现统一的使用界面和API接口,让用户就像使用一个云平台一样使用分布于多云的资源,实现一个统一的“云上之云”的云平台。
|
||||
|
||||
鉴于企业IT基础设施的两个趋势:1. 企业使用多云基础设施,并且公有云是最主要的基础设施提供者;2. 企业应用将逐步云原生化,企业IT基础设施需要为Kubernetes优化。融合云为此架构而设计。一方面抽象管理底层的多云基础设施,另一方面为多云Kubernetes提供运行环境。融合云为企业未来的的IT基础设施架构而设计。
|
||||
|
||||
@@ -18,18 +18,18 @@
|
||||
|
||||
- 内置私有云
|
||||
|
||||
OneCloud内置完备的私有云实现,提供对用户本地IDC的虚拟机、物理机和负载均衡等资源管理。
|
||||
YunionCloud 内置完备的私有云实现,提供对用户本地IDC的虚拟机、物理机和负载均衡等资源管理。
|
||||
|
||||
- 为多云Kubernetes提供运行环境
|
||||
|
||||
OneCloud自身为运行在Kubernetes的云原生应用,并且能在多云环境部署运行Kubernetes集群。
|
||||
YunionCloud 自身为运行在Kubernetes的云原生应用,并且能在多云环境部署运行Kubernetes集群。
|
||||
|
||||
欢迎安装部署云联融合云,期待大家的反馈!
|
||||
|
||||
|
||||
## 部署
|
||||
|
||||
请参考文档 [安装部署](https://docs.yunion.io/docs/setup/) 搭建 OneCloud 集群。
|
||||
请参考文档 [安装部署](https://docs.yunion.io/docs/setup/) 搭建 YunionCloud 集群。
|
||||
|
||||
|
||||
## 文档
|
||||
@@ -51,4 +51,4 @@
|
||||
|
||||
## License
|
||||
|
||||
OneCloud 使用 Apache license 2.0. 详情请看 [LICENSE](./LICENSE) 。
|
||||
YunionCloud 使用 Apache license 2.0. 详情请看 [LICENSE](./LICENSE) 。
|
||||
|
||||
24
README.md
24
README.md
@@ -1,22 +1,22 @@
|
||||
# Yunion OneCloud
|
||||
# Yunion Cloud
|
||||
|
||||
[](https://circleci.com/gh/yunionio/onecloud)
|
||||
[](https://travis-ci.com/yunionio/onecloud/branches)
|
||||
[](https://goreportcard.com/report/github.com/yunionio/onecloud)
|
||||
[](https://circleci.com/gh/yunionio/yunioncloud)
|
||||
[](https://travis-ci.com/yunionio/yunioncloud/branches)
|
||||
[](https://goreportcard.com/report/github.com/yunionio/yunioncloud)
|
||||
|
||||
### [README in Chinese](./README-CN.md)
|
||||
|
||||
## What is Yunion OneCloud?
|
||||
## What is Yunion Cloud?
|
||||
|
||||
Yunion OneCloud is an open source unified-IaaS cloud platform.
|
||||
Yunion Cloud is an open source unified-IaaS cloud platform.
|
||||
|
||||
As its name sugguests, 'Yun' means 'cloud' in Chinese and 'Yunion OneCloud' means to unify many distinct clouds into the one that behaves like an integral cloud platform.
|
||||
As its name sugguests, 'Yun' means 'cloud' in Chinese and 'Yunion Cloud' means to unify many distinct clouds into the one that behaves like an integral cloud platform.
|
||||
|
||||
As trends show, the enterprise IT infrastructure in the future would be unavoidably heterogeneous and the public clouds should be the major infrastructure providers for many enterprises. Further, the infrastructure would most likely be prepared for the cloud-native applications running on Kubernetes. Yunion OneCloud is built to provide the cloud architecture for this scenario such that it is the middle layer between the underlying cloud infrustructures and the overlay kubernetes clusters across many clouds.
|
||||
As trends show, the enterprise IT infrastructure in the future would be unavoidably heterogeneous and the public clouds should be the major infrastructure providers for many enterprises. Further, the infrastructure would most likely be prepared for the cloud-native applications running on Kubernetes. Yunion Cloud is built to provide the cloud architecture for this scenario such that it is the middle layer between the underlying cloud infrustructures and the overlay kubernetes clusters across many clouds.
|
||||
|
||||
Many may consider Yunion OneCloud as a multi-cloud management platform (MCMP). Rather, we would view it as an IaaS platform as it does not only manage the resources and services from many clouds, but also hides the differences of underlying technologies and exposes one set of APIs that allow programatically interacting with the compute/storage/networking resources across many clouds.
|
||||
Many may consider Yunion Cloud as a multi-cloud management platform (MCMP). Rather, we would view it as an IaaS platform as it does not only manage the resources and services from many clouds, but also hides the differences of underlying technologies and exposes one set of APIs that allow programatically interacting with the compute/storage/networking resources across many clouds.
|
||||
|
||||
Yunion OneCloud is working on abstracting APIs for the following resources:
|
||||
Yunion Cloud is working on abstracting APIs for the following resources:
|
||||
|
||||
* Compute, including virtual machines, images, etc.
|
||||
* Storage, including disks, snapshots, object storages, etc.
|
||||
@@ -30,7 +30,7 @@ over the following many cloud providers:
|
||||
* Private clouds, including OpenStack, etc.
|
||||
* Public clouds, including Aliyun, AWS, Azure, Tencent Cloud, Huawei Cloud, etc.
|
||||
|
||||
You are welcome to install and try Yunion OneCloud. Looking forward to your feedback.
|
||||
You are welcome to install and try Yunion Cloud. Looking forward to your feedback.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -38,7 +38,7 @@ Please refers to [install & deployment](https://docs.yunion.io/docs/setup/) (cur
|
||||
|
||||
## Documentations
|
||||
|
||||
- [Yunion OneCloud Documents](https://docs.yunion.io/)
|
||||
- [Yunion Cloud Documents](https://docs.yunion.io/)
|
||||
|
||||
- [Swagger API](https://docs.yunion.cn/apiv2/)
|
||||
|
||||
|
||||
23
build/convert_rpm2deb.sh
Executable file
23
build/convert_rpm2deb.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$ROOT_DIR" ]; then
|
||||
ROOT_DIR=$(dirname $(dirname $(readlink -f "$BASH_SOURCE")))
|
||||
fi
|
||||
|
||||
RPMS_DIR=$ROOT_DIR/_output/rpms
|
||||
DEBS_DIR=$ROOT_DIR/_output/debs
|
||||
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
CURRENT_ARCH=amd64
|
||||
;;
|
||||
aarch64)
|
||||
CURRENT_ARCH=arm64
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p $DEBS_DIR && cd $DEBS_DIR
|
||||
|
||||
find $RPMS_DIR -type f -name *.rpm -exec alien --target=$CURRENT_ARCH {} \;
|
||||
9
build/docker/Dockerfile.debian-base
Normal file
9
build/docker/Dockerfile.debian-base
Normal file
@@ -0,0 +1,9 @@
|
||||
# registry.cn-beijing.aliyuncs.com/yunionio/debian10-base:1.0
|
||||
|
||||
FROM debian:10
|
||||
|
||||
RUN apt update && apt install -y alien
|
||||
|
||||
RUN apt-get clean autoclean && \
|
||||
apt-get autoremove --yes && \
|
||||
rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||
@@ -1,3 +0,0 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunion-rootfs:v1.0
|
||||
|
||||
ADD ./_output/bin/telegraf-raid-plugin /opt/yunion/bin/telegraf-raid-plugin
|
||||
3
build/docker/Dockerfile.telegraf-raid-plugin
Normal file
3
build/docker/Dockerfile.telegraf-raid-plugin
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunion-rootfs:v1.0
|
||||
|
||||
ADD ./_output/centos-build/bin/telegraf-raid-plugin /opt/yunion/bin/telegraf-raid-plugin
|
||||
3
build/docker/Makefile
Normal file
3
build/docker/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
debian10-base:
|
||||
docker buildx build --platform linux/arm64,linux/amd64 --push \
|
||||
-t registry.cn-beijing.aliyuncs.com/yunionio/debian10-base:1.0 -f ./Dockerfile.debian-base .
|
||||
@@ -32,6 +32,8 @@ type GeneralUsageOptions struct {
|
||||
|
||||
CloudEnv string `help:"show usage of specified cloudenv" choices:"public|private|onpremise"`
|
||||
Scope string `help:"show usage of specified privilege scope" choices:"system|domain|project"`
|
||||
|
||||
Refresh bool `help:"force refresh usage statistics"`
|
||||
}
|
||||
|
||||
func fetchHostTypeOptions(args *GeneralUsageOptions) *jsonutils.JSONDict {
|
||||
@@ -48,6 +50,9 @@ func fetchHostTypeOptions(args *GeneralUsageOptions) *jsonutils.JSONDict {
|
||||
if len(args.CloudEnv) > 0 {
|
||||
params.Add(jsonutils.NewString(args.CloudEnv), "cloud_env")
|
||||
}
|
||||
if args.Refresh {
|
||||
params.Add(jsonutils.JSONTrue, "refresh")
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
|
||||
130
cmd/rbdcli/main.go
Normal file
130
cmd/rbdcli/main.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
_ "yunion.io/x/onecloud/cmd/rbdcli/shell"
|
||||
"yunion.io/x/onecloud/pkg/util/rbdutils"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
Help bool `help:"Show help"`
|
||||
Debug bool `help:"debug mode"`
|
||||
MonHost string `help:"Ceph Mon Host" default:"$MON_HOST"`
|
||||
Pool string `help:"Ceph pool" default:"$CEPH_POOL" metavar:"CEPH_POOL"`
|
||||
Key string `help:"Secret" default:"$CEPH_KEY" metavar:"CEPH_KEY"`
|
||||
SUBCOMMAND string `help:"rbdcli subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&BaseOptions{},
|
||||
"rbdcli",
|
||||
"Command-line interface to rbd API.",
|
||||
`See "rbdcli 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) {
|
||||
fmt.Fprintf(os.Stderr, "%s", e)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newPool(opts *BaseOptions) (*rbdutils.SPool, error) {
|
||||
cli, err := rbdutils.NewCluster(opts.MonHost, opts.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pool, err := cli.GetPool(opts.Pool)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetPool(%s)", opts.Pool)
|
||||
}
|
||||
|
||||
return pool, 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())
|
||||
return
|
||||
}
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if e != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(e)
|
||||
return
|
||||
}
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
var pool *rbdutils.SPool
|
||||
pool, e = newPool(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = subcmd.Invoke(pool, suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
51
cmd/rbdcli/shell/cluster.go
Normal file
51
cmd/rbdcli/shell/cluster.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/rbdutils"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type ClusterStatOption struct {
|
||||
}
|
||||
|
||||
shellutils.R(&ClusterStatOption{}, "cluster-stat", "Show Cluster State", func(cli *rbdutils.SPool, args *ClusterStatOption) error {
|
||||
cluster := cli.GetCluster()
|
||||
stat, err := cluster.GetClusterStats()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetClusterStats")
|
||||
}
|
||||
printObject(stat)
|
||||
return nil
|
||||
})
|
||||
|
||||
type CmdOptions struct {
|
||||
CMD string
|
||||
}
|
||||
|
||||
shellutils.R(&CmdOptions{}, "run", "Run Cluster command", func(cli *rbdutils.SPool, args *CmdOptions) error {
|
||||
ret, err := cli.GetCluster().MonCommand([]byte(args.CMD))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "MonCommand")
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
58
cmd/rbdcli/shell/pool.go
Normal file
58
cmd/rbdcli/shell/pool.go
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/rbdutils"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type PoolListOptions struct {
|
||||
}
|
||||
shellutils.R(&PoolListOptions{}, "pool-list", "List pools", func(cli *rbdutils.SPool, args *PoolListOptions) error {
|
||||
cluster := cli.GetCluster()
|
||||
pools, err := cluster.ListPools()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "ListPools")
|
||||
}
|
||||
printObject(jsonutils.Marshal(map[string][]string{"pools": pools}))
|
||||
return nil
|
||||
})
|
||||
|
||||
type PoolDeleteOptions struct {
|
||||
POOL string
|
||||
}
|
||||
|
||||
shellutils.R(&PoolDeleteOptions{}, "pool-delete", "Delete Cluster pool", func(cli *rbdutils.SPool, args *PoolDeleteOptions) error {
|
||||
return cli.GetCluster().DeletePool(args.POOL)
|
||||
})
|
||||
|
||||
type ImageListOptions struct {
|
||||
}
|
||||
|
||||
shellutils.R(&ImageListOptions{}, "image-list", "List Pool images", func(cli *rbdutils.SPool, args *ImageListOptions) error {
|
||||
images, err := cli.ListImages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(jsonutils.Marshal(map[string][]string{"images": images}))
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
25
cmd/rbdcli/shell/printutils.go
Normal file
25
cmd/rbdcli/shell/printutils.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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 shell
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/util/printutils"
|
||||
|
||||
func printList(data interface{}, total, offset, limit int, columns []string) {
|
||||
printutils.PrintInterfaceList(data, total, offset, limit, columns)
|
||||
}
|
||||
|
||||
func printObject(obj interface{}) {
|
||||
printutils.PrintInterfaceObject(obj)
|
||||
}
|
||||
8
go.mod
8
go.mod
@@ -109,7 +109,7 @@ require (
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.10
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24
|
||||
github.com/tinylib/msgp v1.1.0 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
||||
github.com/tredoe/osutil v0.0.0-20161130133508-7d3ee1afa71c
|
||||
@@ -140,13 +140,13 @@ require (
|
||||
k8s.io/apimachinery v0.19.3
|
||||
k8s.io/client-go v0.19.3
|
||||
k8s.io/cluster-bootstrap v0.19.3
|
||||
yunion.io/x/executor v0.0.0-20201201131200-44fa553abd9e
|
||||
yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e
|
||||
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769
|
||||
yunion.io/x/log v0.0.0-20201210064738-43181789dc74
|
||||
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7
|
||||
yunion.io/x/pkg v0.0.0-20201123083159-ca3aea986ff2
|
||||
yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
|
||||
yunion.io/x/sqlchemy v0.0.0-20210204013753-dbac29c9cedb
|
||||
yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce
|
||||
)
|
||||
|
||||
|
||||
17
go.sum
17
go.sum
@@ -583,8 +583,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/syncthing/syncthing v0.14.48-rc.4/go.mod h1:nw3siZwHPA6M8iSfjDCWQ402eqvEIasMQOE8nFOxy7M=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible h1:QIMoFqKCmNp4HPLiTR+couZbHsIZfoOllncHYvtqse8=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.10 h1:hJPLdR4RPsnubB3M9qXNBeUbcOJMVANnO/L6Att/PZU=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.10/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24 h1:ZsZij764lOaPsj7mEAlyxXvslGt6/m312Tzqj/zeRpo=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
@@ -912,8 +912,8 @@ sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/executor v0.0.0-20201201131200-44fa553abd9e h1:NRtqiegW4NME0v10rpChORZnJnuAUbpv31R5DsqqczQ=
|
||||
yunion.io/x/executor v0.0.0-20201201131200-44fa553abd9e/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e h1:uGmKmmHm4zeLXhc/MEbAFtEDtGtyEYhC0OaBRGFi+fQ=
|
||||
yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 h1:LIQ4hhLGQuQK+XxlV+8JrKBuL37WUT+5ZTVxBwHOTD4=
|
||||
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
|
||||
@@ -925,13 +925,12 @@ yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 h1:gjqNa2uQzIEXyySsbvVz0Ult
|
||||
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
|
||||
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6 h1:UarEDTBGkgcgc+nc+PZ75uo9M9+jiOGd5P2B90TxDNw=
|
||||
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20201123083159-ca3aea986ff2 h1:NeCr2J8HjcIuJvEhP0rwWA1UKP8ReOv6HVf5k9YPtyA=
|
||||
yunion.io/x/pkg v0.0.0-20201123083159-ca3aea986ff2/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c h1:J/joqbA1N2mAlOl0Uqd4LpAq3+DK5aoFMdz+p9Ld7pQ=
|
||||
yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210204013753-dbac29c9cedb h1:k7s5xMCd/fw29vUaNsGCrLkyn7w8eSghJ5NChuU9SAk=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210204013753-dbac29c9cedb/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3 h1:C4yasW3gXronDIlIVUqHSbkA38PM1X9gxUWTYGsuIuI=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce h1:kU8xE7O5uZ1GSJVMZHoJ+jrNL7csUQHYGyAPW9QfNpE=
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
@@ -47,5 +48,7 @@ func StartService() {
|
||||
db.EnsureAppInitSyncDB(app, dbOpts, models.InitDB)
|
||||
defer cloudcommon.CloseDB()
|
||||
|
||||
go ReapZomebieLoop(context.TODO())
|
||||
|
||||
common_app.ServeForever(app, baseOpts)
|
||||
}
|
||||
|
||||
118
pkg/ansibleserver/service/zombie.go
Normal file
118
pkg/ansibleserver/service/zombie.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// 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 service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
)
|
||||
|
||||
func ReapZomebieLoop(ctx context.Context) {
|
||||
myPid := os.Getpid()
|
||||
if myPid != 1 {
|
||||
log.Infof("My pid is not 1 and no need to wait zombies")
|
||||
return
|
||||
}
|
||||
myPidStr := fmt.Sprintf("%d", myPid)
|
||||
|
||||
tick := time.NewTicker(31 * time.Second)
|
||||
for {
|
||||
dirs, err := ioutil.ReadDir("/proc")
|
||||
if err != nil {
|
||||
log.Errorf("read /proc dir: %v", err)
|
||||
}
|
||||
for _, dir := range dirs {
|
||||
// /proc/<pid>/
|
||||
if !dir.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := dir.Name()
|
||||
allDigits := true
|
||||
for _, c := range name {
|
||||
if c < '0' || c > '9' {
|
||||
allDigits = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !allDigits {
|
||||
continue
|
||||
}
|
||||
|
||||
// read /proc/<pid>/stat
|
||||
statPath := filepath.Join("/proc", name, "stat")
|
||||
data, err := ioutil.ReadFile(statPath)
|
||||
if err != nil {
|
||||
log.Errorf("read %s: %v", statPath, err)
|
||||
continue
|
||||
}
|
||||
dataStr := string(data)
|
||||
items := strings.Split(dataStr, " ")
|
||||
const (
|
||||
idxPid = iota
|
||||
idxName = iota
|
||||
idxState = iota
|
||||
idxPpid = iota
|
||||
idxMinLen = iota
|
||||
)
|
||||
if len(items) < idxMinLen {
|
||||
log.Errorf("%s contains less than %d items: %s", statPath, idxMinLen, dataStr)
|
||||
}
|
||||
|
||||
// my zombie subprocesses
|
||||
state := items[idxState]
|
||||
if state != "Z" {
|
||||
continue
|
||||
}
|
||||
ppidStr := items[idxPpid]
|
||||
if ppidStr != myPidStr {
|
||||
continue
|
||||
}
|
||||
|
||||
// wait it
|
||||
pname := items[idxName]
|
||||
pidStr := items[idxPid]
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
if err != nil {
|
||||
log.Errorf("%s: %s has invalid pid number %q: %v", pname, statPath, pidStr, err)
|
||||
continue
|
||||
}
|
||||
var (
|
||||
status syscall.WaitStatus
|
||||
rusage syscall.Rusage
|
||||
)
|
||||
pid1, err := syscall.Wait4(pid, &status, 0, &rusage)
|
||||
if err != nil {
|
||||
log.Errorf("%s: %s: wait error: %v", pname, statPath, err)
|
||||
continue
|
||||
}
|
||||
if pid1 == pid {
|
||||
log.Infof("%s: pid %d: wait done", pname, pid)
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-tick.C:
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,6 +361,12 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
return
|
||||
}
|
||||
|
||||
if len(password) == 0 {
|
||||
e := httperrors.NewClientError("row %d password is empty", rowIdx)
|
||||
httperrors.JsonClientError(ctx, w, e)
|
||||
return
|
||||
}
|
||||
|
||||
domainId, ok := domains[domain]
|
||||
if !ok {
|
||||
if len(domain) == 0 {
|
||||
@@ -462,7 +468,7 @@ func (mh *MiscHandler) getDownloadsHandler(ctx context.Context, w http.ResponseW
|
||||
return
|
||||
}
|
||||
case "BatchUserRegister":
|
||||
records := [][]string{{"*用户名(user)", "用户密码(password)", "*部门/域(domain)", "*是否登录控制台(allow_web_console:true、false)"}}
|
||||
records := [][]string{{"*用户名(user)", "*用户密码(password)", "*部门/域(domain)", "*是否登录控制台(allow_web_console:true、false)"}}
|
||||
content, err = writeXlsx("users", records)
|
||||
if err != nil {
|
||||
httperrors.InternalServerError(ctx, w, "internal server error")
|
||||
|
||||
@@ -346,6 +346,14 @@ type CloudaccountPerformPrepareNetsInput struct {
|
||||
HostNumberLowerLimit *int `json:"host_number_lower_limit"`
|
||||
// enum: vcenter,datacenter,cluster
|
||||
WireLevelForVmware string `json:"wire_level_for_vmware"`
|
||||
// description: Whether to directly create the recommended network
|
||||
Create *bool `json:"create"`
|
||||
// description: It is recommended that the name of the network be the same as the native name of vmware
|
||||
OriginNetworkName *bool `json:"origin_network_name"`
|
||||
// description: Created network ip distribution strategy
|
||||
NetworkIpAllocationPolicy string `json:"network_ip_allocation_policy"`
|
||||
// description: zone of wire created
|
||||
WireZone string `json:"wire_zone"`
|
||||
}
|
||||
|
||||
type CloudaccountPerformPrepareNetsOutput struct {
|
||||
@@ -436,3 +444,9 @@ type GetCloudaccountSamlOutput struct {
|
||||
// initial SAML SSO login URL for this cloudaccount
|
||||
InitLoginUrl string `json:"init_login_url,allowempty"`
|
||||
}
|
||||
|
||||
type CloudaccountEnableAutoSyncInput struct {
|
||||
// 云账号状态必须是connected
|
||||
// 最小值为region服务的minimal_sync_interval_seconds
|
||||
SyncIntervalSeconds int `json:"sync_interval_seconds"`
|
||||
}
|
||||
|
||||
@@ -177,6 +177,9 @@ const (
|
||||
// 尼日利亚
|
||||
CITY_LAGOS = "Lagos" //拉哥斯
|
||||
|
||||
// 巴林王国 (中东国家)
|
||||
CITY_BAHRAIN = "Bahrain" // 巴林
|
||||
|
||||
// 越南
|
||||
CITY_HO_CHI_MINH = "Ho Chi Minh" //???
|
||||
|
||||
@@ -207,4 +210,5 @@ const (
|
||||
COUNTRY_CODE_NO = "NO" //挪威
|
||||
COUNTRY_CODE_MX = "MX" //墨西哥
|
||||
COUNTRY_CODE_CL = "CL" //智利
|
||||
COUNTRY_CODE_BH = "BH" //巴林
|
||||
)
|
||||
|
||||
@@ -106,6 +106,7 @@ type DiskListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
apis.MultiArchResourceBaseListInput
|
||||
apis.AutoDeleteResourceBaseListInput
|
||||
billing.BillingResourceListInput
|
||||
StorageFilterListInput
|
||||
|
||||
@@ -134,8 +135,6 @@ type DiskListInput struct {
|
||||
|
||||
DiskSize int `json:"disk_size"`
|
||||
|
||||
AutoDelete *bool `json:"auto_delete"`
|
||||
|
||||
FsFormat string `json:"fs_format"`
|
||||
|
||||
// 镜像
|
||||
|
||||
@@ -171,11 +171,6 @@ const (
|
||||
CPU_MODE_HOST = "host"
|
||||
)
|
||||
|
||||
const (
|
||||
OS_ARCH_X86 = "x86"
|
||||
OS_ARCH_ARM = "arm"
|
||||
)
|
||||
|
||||
var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_BLOCK_STREAM, VM_BLOCK_STREAM_FAIL}
|
||||
var VM_CREATING_STATUS = []string{VM_CREATE_NETWORK, VM_CREATE_DISK, VM_START_DEPLOY, VM_DEPLOYING}
|
||||
|
||||
|
||||
@@ -62,9 +62,9 @@ type ServerListInput struct {
|
||||
// enum: linux,windows,vmware
|
||||
OsType []string `json:"os_type"`
|
||||
|
||||
// 对列表结果按照磁盘进行排序
|
||||
// 对列表结果按照磁盘大小进行排序
|
||||
// enum: asc,desc
|
||||
// OrderByDisk string `json:"order_by_disk"`
|
||||
OrderByDisk string `json:"order_by_disk"`
|
||||
|
||||
// 根据ip查找机器
|
||||
IpAddr string `json:"ip_addr"`
|
||||
@@ -460,3 +460,25 @@ type ServerStopInput struct {
|
||||
// 目前仅阿里云,腾讯云此参数生效
|
||||
StopCharging bool `json:"stop_charging"`
|
||||
}
|
||||
|
||||
type ServerDeleteInput struct {
|
||||
// 是否越过回收站直接删除
|
||||
// default: false
|
||||
OverridePendingDelete bool
|
||||
|
||||
// 是否仅删除本地资源
|
||||
// default: false
|
||||
Purge bool
|
||||
|
||||
// 是否删除快照
|
||||
// default: false
|
||||
DeleteSnapshots bool
|
||||
|
||||
// 是否删除关联的EIP
|
||||
// default: false
|
||||
DeleteEip bool
|
||||
|
||||
// 是否删除关联的数据盘
|
||||
// default: false
|
||||
DeleteDisks bool
|
||||
}
|
||||
|
||||
@@ -131,7 +131,3 @@ const (
|
||||
HOST_HEALTH_STATUS_RUNNING = "running"
|
||||
HOST_HEALTH_LOCK_PREFIX = "host-health"
|
||||
)
|
||||
|
||||
const (
|
||||
CPU_ARCH_AARCH64 = "aarch64"
|
||||
)
|
||||
|
||||
@@ -245,6 +245,9 @@ type LoadbalancerCreateInput struct {
|
||||
// 计费类型
|
||||
ChargeType string `json:"charge_type"`
|
||||
|
||||
// 出口带宽
|
||||
EgressMbps int `json:"egress_mbps"`
|
||||
|
||||
// 套餐名称
|
||||
LoadbalancerSpec string `json:"loadbalancer_spec"`
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package apis
|
||||
|
||||
import "yunion.io/x/pkg/utils"
|
||||
|
||||
const (
|
||||
SERVICE_TYPE_IMAGE = "image"
|
||||
SERVICE_TYPE_OFFLINE_CLOUDMETA = "offlinecloudmeta"
|
||||
@@ -60,3 +62,22 @@ var (
|
||||
SERVICE_TYPE_INFLUXDB,
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
OS_ARCH_X86 = "x86"
|
||||
OS_ARCH_ARM = "arm"
|
||||
|
||||
OS_ARCH_I386 = "i386"
|
||||
OS_ARCH_X86_32 = "x86_32"
|
||||
OS_ARCH_X86_64 = "x86_64"
|
||||
OS_ARCH_AARCH32 = "aarch32"
|
||||
OS_ARCH_AARCH64 = "aarch64"
|
||||
)
|
||||
|
||||
func IsARM(osArch string) bool {
|
||||
return utils.IsInStringArray(osArch, []string{
|
||||
OS_ARCH_ARM,
|
||||
OS_ARCH_AARCH32,
|
||||
OS_ARCH_AARCH64,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -319,3 +319,7 @@ type EnabledStatusInfrasResourceBaseListInput struct {
|
||||
type MultiArchResourceBaseListInput struct {
|
||||
OsArch string `json:"os_arch"`
|
||||
}
|
||||
|
||||
type AutoDeleteResourceBaseListInput struct {
|
||||
AutoDelete *bool
|
||||
}
|
||||
|
||||
147
pkg/apis/monitor/alertquery_const.go
Normal file
147
pkg/apis/monitor/alertquery_const.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package monitor
|
||||
|
||||
var (
|
||||
ServerTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"vm_id": "id",
|
||||
"vm_ip": "ips",
|
||||
"vm_name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"scaling_group_id": "vm_scaling_group_id",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
HostTags = map[string]string{
|
||||
"host_id": "id",
|
||||
"host_ip": "ips",
|
||||
"host": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
RdsTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"rds_id": "id",
|
||||
"rds_ip": "ips",
|
||||
"rds_name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
RedisTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"redis_id": "id",
|
||||
"redis_ip": "ips",
|
||||
"redis_name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
OssTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"oss_id": "id",
|
||||
"oss_ip": "ips",
|
||||
"oss_name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
ElbTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"elb_id": "id",
|
||||
"elb_ip": "ips",
|
||||
"elb_name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"region": "region",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
CloudAccountTags = map[string]string{
|
||||
"cloudaccount_id": "id",
|
||||
"cloudaccount_name": "name",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
TenantTags = map[string]string{
|
||||
"tenant_id": "id",
|
||||
"tenant": "name",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
DomainTags = map[string]string{
|
||||
"domain_id": "id",
|
||||
"project_domain": "name",
|
||||
}
|
||||
)
|
||||
@@ -9,6 +9,8 @@ const (
|
||||
METRIC_RES_TYPE_OSS = "oss"
|
||||
METRIC_RES_TYPE_RDS = "rds"
|
||||
METRIC_RES_TYPE_CLOUDACCOUNT = "cloudaccount"
|
||||
METRIC_RES_TYPE_TENANT = "tenant"
|
||||
METRIC_RES_TYPE_DOMAIN = "domain"
|
||||
|
||||
METRIC_UNIT_PERCENT = "%"
|
||||
METRIC_UNIT_BPS = "bps"
|
||||
|
||||
@@ -21,12 +21,14 @@ var (
|
||||
"cloudaccount": "cloudaccount_name",
|
||||
}
|
||||
MEASUREMENT_TAG_ID = map[string]string{
|
||||
"host": "host_id",
|
||||
"guest": "vm_id",
|
||||
"redis": "redis_id",
|
||||
"rds": "rds_id",
|
||||
"oss": "oss_id",
|
||||
"cloudaccount": "cloudaccount_id",
|
||||
METRIC_RES_TYPE_HOST: "host_id",
|
||||
METRIC_RES_TYPE_GUEST: "vm_id",
|
||||
METRIC_RES_TYPE_REDIS: "redis_id",
|
||||
METRIC_RES_TYPE_RDS: "rds_id",
|
||||
METRIC_RES_TYPE_OSS: "oss_id",
|
||||
METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_id",
|
||||
METRIC_RES_TYPE_TENANT: "tenant_id",
|
||||
METRIC_RES_TYPE_DOMAIN: "domain_id",
|
||||
}
|
||||
AlertReduceFunc = map[string]string{
|
||||
"avg": "average value",
|
||||
|
||||
@@ -93,7 +93,7 @@ func (job *SStatusProbeJob) Name() string {
|
||||
|
||||
func (job *SStatusProbeJob) Do(ctx context.Context, now time.Time) error {
|
||||
bStatus := job.baremetal.GetStatus()
|
||||
if bStatus == api.BAREMETAL_READY || bStatus == api.BAREMETAL_RUNNING {
|
||||
if bStatus == api.BAREMETAL_READY || bStatus == api.BAREMETAL_RUNNING || bStatus == api.BAREMETAL_UNKNOWN {
|
||||
ps, err := job.baremetal.GetPowerStatus()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetPowerStatus")
|
||||
|
||||
@@ -1550,6 +1550,11 @@ func (b *SBaremetalInstance) StartBaremetalResetBMCTask(userCred mcclient.TokenC
|
||||
}
|
||||
|
||||
func (b *SBaremetalInstance) StartBaremetalIpmiProbeTask(userCred mcclient.TokenCredential, taskId string, data jsonutils.JSONObject) error {
|
||||
session := b.manager.GetClientSession()
|
||||
data, _ = b.manager.fetchBaremetal(session, b.GetId())
|
||||
if err := b.SaveDesc(data); err != nil {
|
||||
return err
|
||||
}
|
||||
b.StartNewTask(tasks.NewBaremetalIpmiProbeTask, userCred, taskId, data)
|
||||
return nil
|
||||
}
|
||||
@@ -1685,7 +1690,9 @@ func (b *SBaremetalInstance) SendNicInfo(nic *types.SNicDevInfo, idx int, nicTyp
|
||||
params.Add(jsonutils.NewString(nicType), "nic_type")
|
||||
}
|
||||
params.Add(jsonutils.NewInt(int64(nic.Mtu)), "mtu")
|
||||
params.Add(jsonutils.NewBool(nic.Up), "link_up")
|
||||
if nic.Up != nil {
|
||||
params.Add(jsonutils.NewBool(*nic.Up), "link_up")
|
||||
}
|
||||
if reset {
|
||||
params.Add(jsonutils.JSONTrue, "reset")
|
||||
}
|
||||
|
||||
@@ -190,7 +190,6 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
|
||||
|
||||
ipmiNic := &types.SNicDevInfo{
|
||||
Mac: conf.Mac,
|
||||
Up: false,
|
||||
Speed: 100,
|
||||
Mtu: 1500,
|
||||
}
|
||||
@@ -441,7 +440,7 @@ func (task *sBaremetalPrepareTask) updateBmInfo(cli *ssh.Client, i *baremetalPre
|
||||
}
|
||||
if o.Options.EnablePxeBoot && task.baremetal.EnablePxeBoot() {
|
||||
for _, nicInfo := range i.nicsInfo {
|
||||
if nicInfo.Mac.String() != adminNic.GetMac().String() && nicInfo.Up {
|
||||
if nicInfo.Mac.String() != adminNic.GetMac().String() && nicInfo.Up != nil && *nicInfo.Up {
|
||||
err = task.doNicWireProbe(cli, nicInfo)
|
||||
if err != nil {
|
||||
// ignore the error
|
||||
|
||||
@@ -245,8 +245,9 @@ func (s *sBaremetalRegisterTask) updateIpmiInfo(cli *ssh.Client) {
|
||||
ipmitool.SetDellIPMILanPortShared(ipmiTool)
|
||||
}
|
||||
}
|
||||
up := true
|
||||
var nic = &types.SNicDevInfo{
|
||||
Up: true,
|
||||
Up: &up,
|
||||
Speed: 100,
|
||||
Mtu: 1500,
|
||||
}
|
||||
|
||||
@@ -157,9 +157,10 @@ func (self *SBaremetalIpmiProbeTask) sendIpmiNicInfo(lanConf *types.SIPMILanConf
|
||||
if speed <= 0 {
|
||||
speed = 100
|
||||
}
|
||||
up := true
|
||||
ipmiNic := &types.SNicDevInfo{
|
||||
Mac: lanConf.Mac,
|
||||
Up: true,
|
||||
Up: &up,
|
||||
Speed: speed,
|
||||
Mtu: 1500,
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package ipmitool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
@@ -115,21 +116,21 @@ func (ipmi *LanPlusIPMI) GetMode() string {
|
||||
return "rmcp"
|
||||
}
|
||||
|
||||
func (ipmi *LanPlusIPMI) GetCommand(args ...string) *procutils.Command {
|
||||
func (ipmi *LanPlusIPMI) GetCommand(args ...string) (*procutils.Command, context.CancelFunc) {
|
||||
nArgs := []string{
|
||||
"--signal=KILL",
|
||||
fmt.Sprintf("%s", ipmi.GetDefaultTimeout()),
|
||||
"ipmitool", "-I", "lanplus", "-H", ipmi.host,
|
||||
"-I", "lanplus", "-H", ipmi.host,
|
||||
"-p", fmt.Sprintf("%d", ipmi.port),
|
||||
"-U", ipmi.user,
|
||||
"-P", ipmi.password,
|
||||
}
|
||||
nArgs = append(nArgs, args...)
|
||||
return procutils.NewCommand("timeout", nArgs...)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), ipmi.GetDefaultTimeout())
|
||||
return procutils.NewCommandContext(ctx, "ipmitool", nArgs...), cancel
|
||||
}
|
||||
|
||||
func (ipmi *LanPlusIPMI) ExecuteCommand(args ...string) ([]string, error) {
|
||||
cmd := ipmi.GetCommand(args...)
|
||||
cmd, cancel := ipmi.GetCommand(args...)
|
||||
defer cancel()
|
||||
log.Debugf("[LanPlusIPMI] execute command: %s", cmd.String())
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
@@ -626,7 +626,7 @@ func (a StorcliAdaptor) key() string {
|
||||
}
|
||||
|
||||
func (a *StorcliAdaptor) isComplete() bool {
|
||||
return a.Controller >= 0 && a.key() != ""
|
||||
return a.Controller >= 0 && a.name != "" && a.sn != ""
|
||||
}
|
||||
|
||||
func (a *StorcliAdaptor) parseLine(l string) {
|
||||
|
||||
@@ -56,7 +56,7 @@ func (dev *Mpt2SASRaidPhyDev) parseLine(line string) bool {
|
||||
}
|
||||
switch key {
|
||||
case "Drive Type":
|
||||
if strings.HasSuffix("_HDD", val) {
|
||||
if strings.HasSuffix(val, "_HDD") {
|
||||
dev.Rotate = tristate.True
|
||||
} else {
|
||||
dev.Rotate = tristate.False
|
||||
|
||||
@@ -17,6 +17,7 @@ package cronman
|
||||
import (
|
||||
"container/heap"
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -393,7 +394,7 @@ func (job *SCronJob) runJobInWorker(isStart bool) {
|
||||
log.Debugf("Cron job: %s started", job.Name)
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, appctx.APP_CONTEXT_KEY_APPNAME, "Cron-Service")
|
||||
ctx = context.WithValue(ctx, appctx.APP_CONTEXT_KEY_TASKNAME, job.Name)
|
||||
ctx = context.WithValue(ctx, appctx.APP_CONTEXT_KEY_TASKNAME, fmt.Sprintf("%s-%d", job.Name, time.Now().Unix()))
|
||||
userCred := DefaultAdminSessionGenerator()
|
||||
job.job(ctx, userCred, isStart)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
@@ -40,11 +39,16 @@ func (manager *SMultiArchResourceBaseManager) ListItemFilter(
|
||||
query apis.MultiArchResourceBaseListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
if len(query.OsArch) > 0 {
|
||||
if query.OsArch == compute.OS_ARCH_X86 {
|
||||
if query.OsArch == apis.OS_ARCH_X86 {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Startswith(q.Field("os_arch"), query.OsArch),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("os_arch")),
|
||||
))
|
||||
} else if query.OsArch == apis.OS_ARCH_ARM {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Startswith(q.Field("os_arch"), query.OsArch),
|
||||
sqlchemy.Equals(q.Field("os_arch"), apis.OS_ARCH_AARCH64),
|
||||
))
|
||||
} else {
|
||||
q = q.Startswith("os_arch", query.OsArch)
|
||||
}
|
||||
|
||||
54
pkg/cloudcommon/db/auto_delete.go
Normal file
54
pkg/cloudcommon/db/auto_delete.go
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
|
||||
// Code generated by model-api-gen. DO NOT EDIT.
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
// +onecloud:model-api-gen
|
||||
type SAutoDeleteResourceBase struct {
|
||||
// 是否跟随资源自动删除
|
||||
// example: false
|
||||
AutoDelete bool `nullable:"false" default:"false" get:"user" update:"user" json:"auto_delete"`
|
||||
}
|
||||
|
||||
type SAutoDeleteResourceBaseManager struct{}
|
||||
|
||||
func (manager *SAutoDeleteResourceBaseManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query apis.AutoDeleteResourceBaseListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
if query.AutoDelete != nil {
|
||||
q = q.Equals("auto_delete", *query.AutoDelete)
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (self *SAutoDeleteResourceBase) SetAutoDelete(model IModel, userCred mcclient.TokenCredential, autoDelete bool) error {
|
||||
_, err := Update(model, func() error {
|
||||
self.AutoDelete = autoDelete
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -932,11 +932,7 @@ func (dispatcher *DBModelDispatcher) tryGetModelProperty(ctx context.Context, pr
|
||||
}
|
||||
|
||||
if consts.IsRbacEnabled() {
|
||||
ownerId, err := fetchOwnerId(ctx, dispatcher.modelManager, userCred, query)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
err = isClassRbacAllowed(dispatcher.modelManager, userCred, ownerId, policy.PolicyActionList, property)
|
||||
_, _, err := FetchCheckQueryOwnerScope(ctx, userCred, query, dispatcher.modelManager, policy.PolicyActionList, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/i18n"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
@@ -177,8 +176,10 @@ func (manager *SI18nManager) RemoveI18ns(ctx context.Context, userCred mcclient.
|
||||
}
|
||||
|
||||
func (manager *SI18nManager) SyncI18ns(ctx context.Context, userCred mcclient.TokenCredential, model IModel, table IModelI18nTable) ([]SI18n, []IModelI18nEntry, compare.SyncResult) {
|
||||
lockman.LockClass(ctx, manager, "")
|
||||
defer lockman.ReleaseClass(ctx, manager, "")
|
||||
//// No need to lock SI18nManager, the resources has been lock in the upper layer - QIU Jian, 20210405
|
||||
// lockman.LockClass(ctx, manager, "")
|
||||
// defer lockman.ReleaseClass(ctx, manager, "")
|
||||
|
||||
syncResult := compare.SyncResult{}
|
||||
|
||||
extItems := manager.getExternalI18nItems(ctx, table)
|
||||
@@ -257,7 +258,7 @@ func (manager *SI18nManager) newFromI18n(ctx context.Context, userCred mcclient.
|
||||
}
|
||||
|
||||
func (self *SI18n) updateFromI18n(ctx context.Context, userCred mcclient.TokenCredential, entry IModelI18nEntry) error {
|
||||
_, err := UpdateWithLock(ctx, self, func() error {
|
||||
_, err := Update(self, func() error {
|
||||
self.KeyValue = entry.GetKeyValue()
|
||||
self.Cn = entry.Lookup(i18n.I18N_TAG_CHINESE)
|
||||
self.En = entry.Lookup(i18n.I18N_TAG_ENGLISH)
|
||||
@@ -273,8 +274,8 @@ func (self *SI18n) updateFromI18n(ctx context.Context, userCred mcclient.TokenCr
|
||||
}
|
||||
|
||||
func (self *SI18n) removeI18n(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
// lockman.LockObject(ctx, self)
|
||||
// defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
err := self.Delete(ctx, userCred)
|
||||
return err
|
||||
|
||||
@@ -31,6 +31,7 @@ const (
|
||||
}*/
|
||||
|
||||
type SInMemoryLockRecord struct {
|
||||
key string
|
||||
lock *sync.Mutex
|
||||
cond *sync.Cond
|
||||
holder context.Context
|
||||
@@ -45,6 +46,11 @@ func newInMemoryLockRecord(ctx context.Context) *SInMemoryLockRecord {
|
||||
return &rec
|
||||
}
|
||||
|
||||
func (rec *SInMemoryLockRecord) fatalf(fmtStr string, args ...interface{}) {
|
||||
debug.PrintStack()
|
||||
log.Fatalf(fmtStr, args...)
|
||||
}
|
||||
|
||||
func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
rec.lock.Lock()
|
||||
defer rec.lock.Unlock()
|
||||
@@ -56,18 +62,17 @@ func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("rec.hold=[%p] ctx=[%p] %v", rec.holder, ctx, rec.holder == ctx)
|
||||
log.Debugf("rec.hold=[%p] ctx=[%p] %v key=[%s]", rec.holder, ctx, rec.holder == ctx, rec.key)
|
||||
}
|
||||
|
||||
if rec.holder == ctx {
|
||||
rec.depth += 1
|
||||
if debug_log {
|
||||
log.Infof("lockContext: same ctx, depth: %d [%p]", rec.depth, rec.holder)
|
||||
log.Infof("lockContext: same ctx, depth: %d [%p] key=[%s]", rec.depth, rec.holder, rec.key)
|
||||
}
|
||||
if rec.depth > 32 {
|
||||
// XXX MUST BE BUG ???
|
||||
debug.PrintStack()
|
||||
panic("Too many recursive locks!!!")
|
||||
rec.fatalf("Too many recursive locks!!! key=[%s]", rec.key)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -76,7 +81,7 @@ func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
rec.waiter.Enum(func(ele interface{}) {
|
||||
electx := ele.(context.Context)
|
||||
if electx == ctx {
|
||||
log.Fatalf("try to lock from a waiter context????")
|
||||
rec.fatalf("try to lock from a waiter context???? key=[%s]", rec.key)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -84,7 +89,7 @@ func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("waiter size %d after push", rec.waiter.Len())
|
||||
log.Debugf("Start to wait ... [%p]", ctx)
|
||||
log.Debugf("Start to wait ... [%p] key=[%s]", ctx, rec.key)
|
||||
}
|
||||
|
||||
for rec.holder != nil {
|
||||
@@ -92,13 +97,13 @@ func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("End of wait ... [%p]", ctx)
|
||||
log.Debugf("End of wait ... [%p] key=[%s]", ctx, rec.key)
|
||||
}
|
||||
|
||||
rec.waiter.Pop(ctx)
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("waiter size %d after pop", rec.waiter.Len())
|
||||
log.Debugf("waiter size %d after pop key=[%s]", rec.waiter.Len(), rec.key)
|
||||
}
|
||||
|
||||
rec.holder = ctx
|
||||
@@ -110,18 +115,18 @@ func (rec *SInMemoryLockRecord) unlockContext(ctx context.Context) (needClean bo
|
||||
defer rec.lock.Unlock()
|
||||
|
||||
if rec.holder != ctx {
|
||||
log.Fatalf("try to unlock a wait context???")
|
||||
rec.fatalf("try to unlock a wait context??? key=[%s]", rec.key)
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("unlockContext depth %d [%p]", rec.depth, ctx)
|
||||
log.Debugf("unlockContext depth %d [%p] key=[%s]", rec.depth, ctx, rec.key)
|
||||
}
|
||||
|
||||
rec.depth -= 1
|
||||
|
||||
if rec.depth <= 0 {
|
||||
if debug_log {
|
||||
log.Debugf("depth 0, to release lock for context [%p]", ctx)
|
||||
log.Debugf("depth 0, to release lock for context [%p] key=[%s]", ctx, rec.key)
|
||||
}
|
||||
|
||||
rec.holder = nil
|
||||
@@ -162,7 +167,9 @@ func (lockman *SInMemoryLockManager) getRecord(ctx context.Context, key string,
|
||||
if !new {
|
||||
return nil
|
||||
}
|
||||
lockman.lockTable[key] = newInMemoryLockRecord(ctx)
|
||||
rec := newInMemoryLockRecord(ctx)
|
||||
rec.key = key
|
||||
lockman.lockTable[key] = rec
|
||||
}
|
||||
return lockman.lockTable[key]
|
||||
}
|
||||
|
||||
@@ -245,9 +245,15 @@ func (manager *SMetadataManager) metaDataQuery2List(ctx context.Context, q *sqlc
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Query.All")
|
||||
}
|
||||
ciMap := map[string]string{}
|
||||
|
||||
ret := make([]jsonutils.JSONObject, len(metadatas))
|
||||
for i := range metadatas {
|
||||
if k, ok := ciMap[strings.ToLower(metadatas[i].Key)]; !ok {
|
||||
ciMap[strings.ToLower(metadatas[i].Key)] = metadatas[i].Key
|
||||
} else {
|
||||
metadatas[i].Key = k
|
||||
}
|
||||
if input.Details != nil && *input.Details {
|
||||
ret[i], err = manager.getKeyValueObjectCount(ctx, userCred, input, metadatas[i].Key, metadatas[i].Value, metadatas[i].Count)
|
||||
if err != nil {
|
||||
|
||||
@@ -385,7 +385,7 @@ func (self *SOpsLogManager) FilterByOwner(q *sqlchemy.SQuery, ownerId mcclient.I
|
||||
}
|
||||
case rbacutils.ScopeDomain:
|
||||
if len(ownerId.GetProjectDomainId()) > 0 {
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("domain_id"), ownerId.GetProjectDomainId()))
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("project_domain_id"), ownerId.GetProjectDomainId()))
|
||||
}
|
||||
default:
|
||||
// systemScope, no filter
|
||||
|
||||
@@ -37,8 +37,8 @@ func Error2TaskData(err error) jsonutils.JSONObject {
|
||||
return errJson
|
||||
}
|
||||
|
||||
func LocalTaskRun(task ITask, proc func() (jsonutils.JSONObject, error)) {
|
||||
localTaskWorkerMan.Run(func() {
|
||||
func LocalTaskRunWithWorkers(task ITask, proc func() (jsonutils.JSONObject, error), wm *appsrv.SWorkerManager) {
|
||||
wm.Run(func() {
|
||||
|
||||
log.Debugf("XXXXXXXXXXXXXXXXXXLOCAL TASK RUN STARTXXXXXXXXXXXXXXXXX")
|
||||
defer log.Debugf("XXXXXXXXXXXXXXXXXXLOCAL TASK RUN END XXXXXXXXXXXXXXXXX")
|
||||
@@ -59,3 +59,7 @@ func LocalTaskRun(task ITask, proc func() (jsonutils.JSONObject, error)) {
|
||||
|
||||
}, nil, nil)
|
||||
}
|
||||
|
||||
func LocalTaskRun(task ITask, proc func() (jsonutils.JSONObject, error)) {
|
||||
LocalTaskRunWithWorkers(task, proc, localTaskWorkerMan)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ type SNicDevInfo struct {
|
||||
Dev string `json:"dev"`
|
||||
Mac net.HardwareAddr `json:"mac"`
|
||||
Speed int `json:"speed"`
|
||||
Up bool `json:"up"`
|
||||
Up *bool `json:"up"`
|
||||
Mtu int `json:"mtu"`
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,8 @@ type ICloudProviderFactory interface {
|
||||
GetTTLRange(zoneType TDnsZoneType, productType TDnsProductType) TTlRange
|
||||
|
||||
IsSupportSAMLAuth() bool
|
||||
|
||||
GetAccountIdEqualizer() func(origin, now string) bool
|
||||
}
|
||||
|
||||
type ICloudProvider interface {
|
||||
@@ -711,6 +713,15 @@ func (factory *baseProviderFactory) GetTTLRange(zoneType TDnsZoneType, productTy
|
||||
return TTlRange{}
|
||||
}
|
||||
|
||||
func (factory *baseProviderFactory) GetAccountIdEqualizer() func(origin, now string) bool {
|
||||
return func(origin, now string) bool {
|
||||
if len(now) > 0 && now != origin {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
type SDnsCapability struct {
|
||||
ZoneTypes []TDnsZoneType
|
||||
DnsTypes map[TDnsZoneType][]TDnsType
|
||||
|
||||
@@ -197,14 +197,6 @@ func (self *SAliyunGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAliyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
}
|
||||
return userName
|
||||
}
|
||||
|
||||
func (self *SAliyunGuestDriver) AllowReconfigGuest() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package guestdrivers
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
@@ -61,14 +60,6 @@ func (self *SApsaraGuestDriver) GetGuestInitialStateAfterRebuild() string {
|
||||
return api.VM_READY
|
||||
}
|
||||
|
||||
func (self *SApsaraGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
}
|
||||
return userName
|
||||
}
|
||||
|
||||
func (self *SApsaraGuestDriver) AllowReconfigGuest() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -119,10 +120,9 @@ func (self *SAwsGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapa
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAwsGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
// return fetchAwsUserName(desc)
|
||||
if desc.OsType == "Windows" {
|
||||
return api.VM_AWS_DEFAULT_WINDOWS_LOGIN_USER
|
||||
func (self *SAwsGuestDriver) GetDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
if strings.ToLower(desc.OsType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) {
|
||||
return api.VM_DEFAULT_WINDOWS_LOGIN_USER
|
||||
}
|
||||
|
||||
return api.VM_AWS_DEFAULT_LOGIN_USER
|
||||
|
||||
@@ -252,7 +252,7 @@ func (self *SAzureGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCa
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
func (self *SAzureGuestDriver) GetDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
return api.VM_AZURE_DEFAULT_LOGIN_USER
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
@@ -328,12 +330,11 @@ func (self *SBaseGuestDriver) GetUserDataType() string {
|
||||
return cloudprovider.CLOUD_CONFIG
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
func (self *SBaseGuestDriver) GetDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
if strings.ToLower(desc.OsType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) {
|
||||
return api.VM_DEFAULT_WINDOWS_LOGIN_USER
|
||||
}
|
||||
return userName
|
||||
return api.VM_DEFAULT_LINUX_LOGIN_USER
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) OnGuestChangeCpuMemFailed(ctx context.Context, guest *models.SGuest, data *jsonutils.JSONDict, task taskman.ITask) error {
|
||||
|
||||
@@ -113,14 +113,6 @@ func (self *SCtyunGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *mo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
if desc.OsType == "Windows" {
|
||||
return "Administrator"
|
||||
}
|
||||
|
||||
return "root"
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SCtyunGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
|
||||
@@ -139,14 +139,6 @@ func (self *SHuaweiGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHuaweiGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
}
|
||||
return userName
|
||||
}
|
||||
|
||||
func (self *SHuaweiGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
|
||||
months := bc.GetMonths()
|
||||
if (months >= 1 && months <= 9) || (months == 12) || (months == 24) || (months == 36) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -382,7 +383,7 @@ func (self *SKVMGuestDriver) RequestAssociateEip(ctx context.Context, userCred m
|
||||
func (self *SKVMGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
|
||||
return guest.GetMetadata("hotplug_cpu_mem", nil) != "enable" ||
|
||||
(memChanged && guest.GetMetadata("__hugepage", nil) == "native") ||
|
||||
guest.OsArch == api.OS_ARCH_ARM
|
||||
apis.IsARM(guest.OsArch)
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
|
||||
|
||||
@@ -343,7 +343,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
|
||||
}
|
||||
}
|
||||
|
||||
desc.Account = guest.GetDriver().GetLinuxDefaultAccount(desc)
|
||||
desc.Account = guest.GetDriver().GetDefaultAccount(desc)
|
||||
|
||||
if guest.GetDriver().IsNeedInjectPasswordByCloudInit(&desc) {
|
||||
err = desc.InjectPasswordByCloudInit()
|
||||
@@ -430,14 +430,6 @@ func (self *SManagedVirtualizedGuestDriver) GetGuestInitialStateAfterRebuild() s
|
||||
return api.VM_READY
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizedGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if strings.ToLower(desc.OsType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) {
|
||||
userName = "Administrator"
|
||||
}
|
||||
return userName
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, desc cloudprovider.SManagedVMCreateConfig) (jsonutils.JSONObject, error) {
|
||||
ihost, err := host.GetIHost()
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,9 @@ package guestdrivers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -280,16 +282,17 @@ func (self *SQcloudGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SQcloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
func (self *SQcloudGuestDriver) GetDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := api.VM_DEFAULT_LINUX_LOGIN_USER
|
||||
if desc.ImageType == "system" {
|
||||
if desc.OsDistribution == "Ubuntu" {
|
||||
userName = "ubuntu"
|
||||
}
|
||||
}
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
if strings.ToLower(desc.OsType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) {
|
||||
userName = api.VM_DEFAULT_WINDOWS_LOGIN_USER
|
||||
}
|
||||
|
||||
return userName
|
||||
}
|
||||
|
||||
|
||||
@@ -111,14 +111,6 @@ func (self *SUCloudGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SUCloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
if desc.OsType == "Windows" {
|
||||
return "Administrator"
|
||||
}
|
||||
|
||||
return "root"
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SUCloudGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
|
||||
@@ -23,11 +23,13 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/compute/options"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
@@ -69,7 +71,11 @@ func (self *SVirtualizedGuestDriver) GetNamedNetworkConfiguration(guest *models.
|
||||
Ifname: "",
|
||||
})
|
||||
}
|
||||
return net, nicConfs, api.IPAllocationStepdown, false
|
||||
reUse := false
|
||||
if len(netConfig.Address) > 0 && !options.Options.EnablePreAllocateIpAddr && !utils.IsInStringArray(host.GetProviderName(), []string{api.CLOUD_PROVIDER_ONECLOUD, api.CLOUD_PROVIDER_VMWARE}) {
|
||||
reUse = true
|
||||
}
|
||||
return net, nicConfs, api.IPAllocationStepdown, reUse
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) GetRandomNetworkTypes() []string {
|
||||
|
||||
@@ -173,14 +173,6 @@ func (self *SZStackGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SZStackGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
userName := "root"
|
||||
if desc.OsType == "Windows" {
|
||||
userName = "Administrator"
|
||||
}
|
||||
return userName
|
||||
}
|
||||
|
||||
func (self *SZStackGuestDriver) AllowReconfigGuest() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -256,3 +256,7 @@ func (driver *SBaseHostDriver) GetStoragecacheQuota(host *models.SHost) int {
|
||||
func (driver *SBaseHostDriver) RequestDeallocateBackupDiskOnHost(ctx context.Context, host *models.SHost, storage *models.SStorage, disk *models.SDisk, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (driver *SBaseHostDriver) RequestSyncOnHost(ctx context.Context, host *models.SHost, task taskman.ITask) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/cmdline"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/baremetal"
|
||||
@@ -156,18 +157,18 @@ func (self *SKVMHostDriver) CheckAndSetCacheImage(ctx context.Context, host *mod
|
||||
params := task.GetParams()
|
||||
imageId, err := params.GetString("image_id")
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "Get image_id from params")
|
||||
}
|
||||
format, _ := params.GetString("format")
|
||||
isForce := jsonutils.QueryBoolean(params, "is_force", false)
|
||||
obj, err := models.CachedimageManager.FetchById(imageId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheImage := obj.(*models.SCachedimage)
|
||||
srcHostCacheImage, err := cacheImage.ChooseSourceStoragecacheInRange(api.HOST_TYPE_HYPERVISOR, []string{host.Id}, []interface{}{host.GetZone()})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
srcHostId, _ := params.GetString("source_host_id")
|
||||
var srcHost *models.SHost
|
||||
if srcHostId != "" {
|
||||
srcHost = models.HostManager.FetchHostById(srcHostId)
|
||||
if srcHost == nil {
|
||||
return errors.Errorf("Source host %s not found", srcHostId)
|
||||
}
|
||||
}
|
||||
|
||||
type contentStruct struct {
|
||||
@@ -182,17 +183,33 @@ func (self *SKVMHostDriver) CheckAndSetCacheImage(ctx context.Context, host *mod
|
||||
content.ImageId = imageId
|
||||
content.Format = format
|
||||
|
||||
obj, err := models.CachedimageManager.FetchById(imageId)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Fetch cached image by image_id %s", imageId)
|
||||
}
|
||||
cacheImage := obj.(*models.SCachedimage)
|
||||
rangeObjs := []interface{}{host.GetZone()}
|
||||
if srcHost != nil {
|
||||
rangeObjs = append(rangeObjs, srcHost)
|
||||
}
|
||||
srcHostCacheImage, err := cacheImage.ChooseSourceStoragecacheInRange(api.HOST_TYPE_HYPERVISOR, []string{host.Id}, rangeObjs)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Choose source storagecache")
|
||||
}
|
||||
if srcHostCacheImage != nil {
|
||||
err = srcHostCacheImage.AddDownloadRefcount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srcHost, err := srcHostCacheImage.GetHost()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "Get storage cached image %s host", srcHostCacheImage.GetId())
|
||||
}
|
||||
content.SrcUrl = fmt.Sprintf("%s/download/images/%s", srcHost.ManagerUri, imageId)
|
||||
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/disks/image_cache", host.ManagerUri)
|
||||
|
||||
if isForce {
|
||||
@@ -206,7 +223,7 @@ func (self *SKVMHostDriver) CheckAndSetCacheImage(ctx context.Context, host *mod
|
||||
|
||||
_, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "POST %s", url)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -589,3 +606,26 @@ func (self *SKVMHostDriver) tryCleanKubernetesData(host *models.SHost, hostname
|
||||
}
|
||||
return cli.Nodes().Delete(context.Background(), hostname, metav1.DeleteOptions{})
|
||||
}
|
||||
|
||||
func (self *SKVMHostDriver) RequestSyncOnHost(ctx context.Context, host *models.SHost, task taskman.ITask) error {
|
||||
log.Infof("Deallocating disk on host %s", host.GetName())
|
||||
header := mcclient.GetTokenHeaders(task.GetUserCred())
|
||||
url := fmt.Sprintf("/hosts/%s/sync", host.Id)
|
||||
body := jsonutils.NewDict()
|
||||
desc := self.GetJsonFromHost(ctx, host)
|
||||
body.Add(desc, "desc")
|
||||
_, err := host.Request(ctx, task.GetUserCred(), "POST", url, header, body)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SKVMHostDriver) GetJsonFromHost(ctx context.Context, host *models.SHost) *jsonutils.JSONDict {
|
||||
desc := jsonutils.NewDict()
|
||||
desc.Add(jsonutils.NewString(host.Name), "name")
|
||||
// tenant
|
||||
domainFetcher, _ := db.DefaultDomainFetcher(ctx, host.DomainId)
|
||||
if domainFetcher != nil {
|
||||
desc.Add(jsonutils.NewString(domainFetcher.GetProjectDomainId()), "domain_id")
|
||||
desc.Add(jsonutils.NewString(domainFetcher.GetProjectDomain()), "project_domain")
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
@@ -166,6 +166,11 @@ func (self *SCachedimage) GetHypervisor() string {
|
||||
return osType
|
||||
}
|
||||
|
||||
func (self *SCachedimage) GetChecksum() string {
|
||||
checksum, _ := self.Info.GetString("checksum")
|
||||
return checksum
|
||||
}
|
||||
|
||||
func (self *SCachedimage) getStoragecacheQuery() *sqlchemy.SQuery {
|
||||
q := StoragecachedimageManager.Query().Equals("cachedimage_id", self.Id)
|
||||
return q
|
||||
@@ -446,6 +451,8 @@ func (self *SCachedimage) ChooseSourceStoragecacheInRange(hostType string, exclu
|
||||
|
||||
for _, rangeObj := range rangeObjs {
|
||||
switch v := rangeObj.(type) {
|
||||
case *SHost:
|
||||
q = q.Filter(sqlchemy.Equals(host.Field("id"), v.Id))
|
||||
case *SZone:
|
||||
q = q.Filter(sqlchemy.Equals(host.Field("zone_id"), v.Id))
|
||||
case *SCloudprovider:
|
||||
|
||||
@@ -54,6 +54,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/choices"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/nopanic"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
@@ -469,6 +470,18 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
|
||||
hostNumberLowerLimit = *input.HostNumberLowerLimit
|
||||
}
|
||||
|
||||
var wireZoneId string
|
||||
if len(input.WireZone) > 0 {
|
||||
zone, err := ZoneManager.FetchByIdOrName(userCred, input.WireZone)
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return output, httperrors.NewInputParameterError("no such zone %s", input.WireZone)
|
||||
}
|
||||
if err != nil {
|
||||
return output, errors.Wrapf(err, "unable to fetch zone %s", input.WireZone)
|
||||
}
|
||||
wireZoneId = zone.GetId()
|
||||
}
|
||||
|
||||
ownerId, err := scm.FetchOwnerId(ctx, jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return output, errors.Wrap(err, "FetchOwnerId in PerformPrepareNets")
|
||||
@@ -559,6 +572,7 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
log.Infof("nInfos: %s", jsonutils.Marshal(nInfos))
|
||||
// fetch networks
|
||||
networks := make([][]SNetwork, len(wires))
|
||||
for i := range networks {
|
||||
@@ -568,7 +582,11 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
|
||||
}
|
||||
networks[i] = nets
|
||||
}
|
||||
return scm.parseAndSuggest(sParseAndSuggest{
|
||||
var originNetworkName bool
|
||||
if input.OriginNetworkName != nil {
|
||||
originNetworkName = *input.OriginNetworkName
|
||||
}
|
||||
output = scm.parseAndSuggest(sParseAndSuggest{
|
||||
NInfos: nInfos,
|
||||
AccountName: input.Name,
|
||||
ZoneIds: zoneids,
|
||||
@@ -577,7 +595,58 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
|
||||
NetworkBits: networkBits,
|
||||
HostNumberUpperLimit: hostNumberUpperLimit,
|
||||
HostNumberLowerLimit: hostNumberLowerLimit,
|
||||
}), nil
|
||||
OriginNetworkName: originNetworkName,
|
||||
})
|
||||
if input.Create == nil || !*input.Create {
|
||||
return output, nil
|
||||
}
|
||||
go nopanic.Run(func() {
|
||||
log.Infof("start to create networks for cloudaccount %s, total %d wires", input.Name, len(output.CAWireNets))
|
||||
// make sure ip allocation policy
|
||||
policy := api.IPAllocationDirection(input.NetworkIpAllocationPolicy)
|
||||
switch policy {
|
||||
case api.IPAllocationStepup, api.IPAllocationStepdown, api.IPAllocationRadnom:
|
||||
default:
|
||||
policy = api.IPAllocationDefault
|
||||
}
|
||||
errs := make([]string, 0)
|
||||
for _, wireNet := range output.CAWireNets {
|
||||
wireId := wireNet.SuitableWire
|
||||
if len(wireId) == 0 {
|
||||
zoneId := wireZoneId
|
||||
if len(zoneId) == 0 {
|
||||
zoneId = wireNet.SuggestedWire.ZoneIds[0]
|
||||
}
|
||||
wireId, err = scm.createWire(ctx, api.DEFAULT_VPC_ID, zoneId, wireNet.SuggestedWire.Name, domainId, wireNet.SuggestedWire.Description)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "create wire %s failed", wireNet.SuggestedWire.Name).Error())
|
||||
continue
|
||||
}
|
||||
}
|
||||
log.Infof("start to create networks for wire %s", wireId)
|
||||
for _, net := range wireNet.HostSuggestedNetworks {
|
||||
err := scm.createNetwork(ctx, domainId, input.ProjectId, wireId, api.NETWORK_TYPE_BAREMETAL, net, policy)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "create host network %s for wire %s failed", jsonutils.Marshal(net), wireId).Error())
|
||||
continue
|
||||
}
|
||||
}
|
||||
for _, net := range wireNet.GuestSuggestedNetworks {
|
||||
err := scm.createNetwork(ctx, domainId, input.ProjectId, wireId, api.NETWORK_TYPE_GUEST, net, policy)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "create guest network %s for wire %s failed", jsonutils.Marshal(net), wireId).Error())
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
errStr := strings.Join(errs, "\n")
|
||||
err = errors.Error(errStr)
|
||||
}
|
||||
log.Infof("end create networks for cloudaccount %s, err: %s", input.Name, err)
|
||||
return
|
||||
})
|
||||
return output, nil
|
||||
}
|
||||
|
||||
type sParseAndSuggest struct {
|
||||
@@ -589,6 +658,60 @@ type sParseAndSuggest struct {
|
||||
NetworkBits int8
|
||||
HostNumberUpperLimit int
|
||||
HostNumberLowerLimit int
|
||||
OriginNetworkName bool
|
||||
}
|
||||
|
||||
func (self *SCloudaccountManager) createWire(ctx context.Context, vpcId, zoneId, wireName, domainId, desc string) (string, error) {
|
||||
wire := &SWire{
|
||||
Bandwidth: 10000,
|
||||
Mtu: 1500,
|
||||
}
|
||||
wire.VpcId = vpcId
|
||||
wire.ZoneId = zoneId
|
||||
wire.IsEmulated = false
|
||||
wire.Name = wireName
|
||||
wire.DomainId = domainId
|
||||
wire.Description = desc
|
||||
wire.IsPublic = true
|
||||
wire.PublicScope = "system"
|
||||
wire.PublicSrc = "local"
|
||||
wire.SetModelManager(WireManager, wire)
|
||||
err := WireManager.TableSpec().Insert(ctx, wire)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Infof("create wire %s succussfully", wire.GetId())
|
||||
return wire.GetId(), nil
|
||||
}
|
||||
|
||||
func (self *SCloudaccountManager) createNetwork(ctx context.Context, domainId, projectId, wireId, networkType string, net api.CANetConf, policy api.IPAllocationDirection) error {
|
||||
network := &SNetwork{}
|
||||
network.Name = net.Name
|
||||
if hint, err := NetworkManager.NewIfnameHint(net.Name); err != nil {
|
||||
log.Errorf("can't NewIfnameHint form hint %s", net.Name)
|
||||
} else {
|
||||
network.IfnameHint = hint
|
||||
}
|
||||
network.GuestIpStart = net.GuestIpStart
|
||||
network.GuestIpEnd = net.GuestIpEnd
|
||||
network.GuestIpMask = net.GuestIpMask
|
||||
network.GuestGateway = net.GuestGateway
|
||||
network.VlanId = int(net.VlanID)
|
||||
network.WireId = wireId
|
||||
network.ServerType = networkType
|
||||
network.IsPublic = true
|
||||
network.Status = api.NETWORK_STATUS_AVAILABLE
|
||||
network.PublicScope = string(rbacutils.ScopeSystem)
|
||||
network.ProjectId = projectId
|
||||
network.DomainId = domainId
|
||||
network.Description = net.Description
|
||||
network.AllocPolicy = string(policy)
|
||||
|
||||
network.SetModelManager(NetworkManager, network)
|
||||
// TODO: Prevent IP conflict
|
||||
log.Infof("create network %s succussfully", network.Id)
|
||||
err := NetworkManager.TableSpec().Insert(ctx, network)
|
||||
return err
|
||||
}
|
||||
|
||||
func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.CloudaccountPerformPrepareNetsOutput {
|
||||
@@ -627,8 +750,9 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
output.CAWireNets = make([]api.CAWireNet, 0, len(nInfos))
|
||||
for _, ni := range nInfos {
|
||||
var (
|
||||
wireNet api.CAWireNet
|
||||
hostIps = ni.HostIps
|
||||
wireNet api.CAWireNet
|
||||
hostIps = ni.HostIps
|
||||
prefixNetworkIndex = 0
|
||||
)
|
||||
|
||||
// key of ipHosts is host's ip
|
||||
@@ -672,9 +796,13 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
if suitableWire != nil {
|
||||
wireNet.SuitableWire = suitableWire.GetId()
|
||||
} else {
|
||||
wireName := ni.prefix
|
||||
if params.OriginNetworkName && len(ni.DVSs) > 0 && len(ni.DVSs) < 3 {
|
||||
wireName = strings.Join(ni.DVSs, "-")
|
||||
}
|
||||
wireNet.SuggestedWire = api.CAWireConf{
|
||||
ZoneIds: params.ZoneIds,
|
||||
Name: ni.prefix + "-wire",
|
||||
Name: wireName,
|
||||
Description: fmt.Sprintf("Auto created Wire for VMware account %q", params.AccountName),
|
||||
}
|
||||
}
|
||||
@@ -699,7 +827,7 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
confs := make([]api.CANetConf, len(sConfs))
|
||||
for i := range confs {
|
||||
confs[i].CASimpleNetConf = sConfs[i]
|
||||
confs[i].Name = fmt.Sprintf("%s-host-network-%d", ni.prefix, i+1)
|
||||
confs[i].Name = fmt.Sprintf("%s-host-%d", ni.prefix, i+1)
|
||||
}
|
||||
wireNet.HostSuggestedNetworks = confs
|
||||
}
|
||||
@@ -731,7 +859,10 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
}
|
||||
wireNet.Guests = guests
|
||||
|
||||
for vlan, ips := range ni.VlanIps {
|
||||
for vlanid, vlan := range ni.VlanIps {
|
||||
ips := vlan.Ips
|
||||
networkIndex := 0
|
||||
networkNameCommon := strings.Join(vlan.PortGroups, "-")
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
if _, ok := existedNets.Get(ip); ok {
|
||||
@@ -740,6 +871,9 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
net := ip.NetAddr(params.NetworkBits)
|
||||
netLimitLow := net + netutils.IPV4Addr(params.HostNumberLowerLimit)
|
||||
netLimitUp := net + netutils.IPV4Addr(params.HostNumberUpperLimit)
|
||||
if ip < netLimitLow || ip > netLimitUp {
|
||||
break
|
||||
}
|
||||
// find startip
|
||||
startIp := ip - 1
|
||||
for ; startIp >= netLimitLow; startIp-- {
|
||||
@@ -756,7 +890,7 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
break
|
||||
}
|
||||
if proc, ok := ipPool.Get(endIp); ok {
|
||||
if proc.VlanId == vlan && proc.VSId == ni.fakeVsId {
|
||||
if proc.VlanId == vlanid && proc.VSId == ni.fakeVsId {
|
||||
// find one in ips
|
||||
i++
|
||||
continue
|
||||
@@ -764,12 +898,25 @@ func (scm *SCloudaccountManager) parseAndSuggest(params sParseAndSuggest) api.Cl
|
||||
break
|
||||
}
|
||||
}
|
||||
slen := len(wireNet.GuestSuggestedNetworks)
|
||||
networkName := networkNameCommon
|
||||
if networkIndex > 0 {
|
||||
networkName = fmt.Sprintf("%s-%d", networkNameCommon, networkIndex)
|
||||
}
|
||||
if !params.OriginNetworkName || (vlanid <= 0 && (len(vlan.PortGroups) == 0 || len(vlan.PortGroups) > 3)) {
|
||||
if prefixNetworkIndex > 0 {
|
||||
networkName = fmt.Sprintf("%s-%d", ni.prefix, prefixNetworkIndex)
|
||||
} else {
|
||||
networkName = fmt.Sprintf("%s", ni.prefix)
|
||||
}
|
||||
prefixNetworkIndex++
|
||||
networkIndex--
|
||||
}
|
||||
networkIndex++
|
||||
wireNet.GuestSuggestedNetworks = append(wireNet.GuestSuggestedNetworks, api.CANetConf{
|
||||
Name: fmt.Sprintf("%s-guest-network-%d", ni.prefix, slen+1),
|
||||
Name: networkName,
|
||||
Description: "",
|
||||
CASimpleNetConf: api.CASimpleNetConf{
|
||||
VlanID: vlan,
|
||||
VlanID: vlanid,
|
||||
GuestIpStart: (startIp + 1).String(),
|
||||
GuestIpEnd: (endIp - 1).String(),
|
||||
GuestIpMask: params.NetworkBits,
|
||||
@@ -1378,8 +1525,10 @@ func (self *SCloudaccount) PerformUpdateCredential(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid cloud account info error: %s", err.Error())
|
||||
}
|
||||
|
||||
isEqual := providerDriver.GetAccountIdEqualizer()
|
||||
// for backward compatibility
|
||||
if len(self.AccountId) > 0 && accountId != self.AccountId {
|
||||
if !isEqual(self.AccountId, accountId) {
|
||||
return nil, httperrors.NewConflictError("inconsistent account_id, previous '%s' and now '%s'", self.AccountId, accountId)
|
||||
}
|
||||
|
||||
@@ -2346,7 +2495,7 @@ func (self *SCloudaccount) AllowPerformEnableAutoSync(ctx context.Context, userC
|
||||
return db.IsAdminAllowPerform(userCred, self, "enable-auto-sync")
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) PerformEnableAutoSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func (self *SCloudaccount) PerformEnableAutoSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudaccountEnableAutoSyncInput) (jsonutils.JSONObject, error) {
|
||||
if self.EnableAutoSync {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -2355,10 +2504,11 @@ func (self *SCloudaccount) PerformEnableAutoSync(ctx context.Context, userCred m
|
||||
return nil, httperrors.NewInvalidStatusError("cannot enable auto sync in status %s", self.Status)
|
||||
}
|
||||
|
||||
syncIntervalSecs := int64(0)
|
||||
syncIntervalSecs, _ = data.Int("sync_interval_seconds")
|
||||
if input.SyncIntervalSeconds < options.Options.MinimalSyncIntervalSeconds {
|
||||
return nil, httperrors.NewOutOfRangeError("sync_interval_seconds should be greater than %d", options.Options.MinimalSyncIntervalSeconds)
|
||||
}
|
||||
|
||||
self.enableAutoSync(ctx, userCred, int(syncIntervalSecs))
|
||||
self.enableAutoSync(ctx, userCred, input.SyncIntervalSeconds)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -2476,6 +2626,9 @@ func (account *SCloudaccount) needSync() bool {
|
||||
if time.Now().Sub(account.LastSyncEndAt) > time.Duration(account.getSyncIntervalSeconds())*time.Second {
|
||||
return true
|
||||
}
|
||||
if account.EnableAutoSync && !account.LastAutoSync.IsZero() && time.Now().Sub(account.LastAutoSync) > time.Duration(account.getSyncIntervalSeconds()-1)*time.Second {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2500,7 +2653,7 @@ func (manager *SCloudaccountManager) initAllRecords() {
|
||||
|
||||
func (self *SCloudaccount) CanSync() bool {
|
||||
if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_QUEUED || self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING || self.getSyncStatus2() == api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING {
|
||||
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > 1800*time.Second {
|
||||
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > time.Duration(self.getSyncIntervalSeconds())*time.Second {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
||||
@@ -44,12 +44,20 @@ func structureTestData() (sParseAndSuggest, error) {
|
||||
"host2": hip + 2,
|
||||
"host3": hip + 3,
|
||||
}
|
||||
ninfo.VlanIps = make(map[int32][]netutils.IPV4Addr)
|
||||
ninfo.VlanIps = make(map[int32]*esxi.SVlan)
|
||||
ninfo.IPPool = esxi.NewIPPool()
|
||||
for _, vlanip := range vlanips {
|
||||
for _, vlan := range vlanip.Vlans {
|
||||
ips, _ := transferIps(vlan.Ips)
|
||||
ninfo.VlanIps[vlan.Id] = append(ninfo.VlanIps[vlan.Id], ips...)
|
||||
eVlan, ok := ninfo.VlanIps[vlan.Id]
|
||||
if !ok {
|
||||
eVlan = &esxi.SVlan{
|
||||
Id: vlan.Id,
|
||||
Ips: []netutils.IPV4Addr{},
|
||||
}
|
||||
ninfo.VlanIps[vlan.Id] = eVlan
|
||||
}
|
||||
eVlan.Ips = append(eVlan.Ips, ips...)
|
||||
for _, ip := range ips {
|
||||
ninfo.IPPool.Insert(ip, esxi.SIPProc{
|
||||
VlanId: vlan.Id,
|
||||
@@ -66,9 +74,9 @@ func structureTestData() (sParseAndSuggest, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, ips := range ninfo.VlanIps {
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
return ips[i] < ips[j]
|
||||
for _, vlan := range ninfo.VlanIps {
|
||||
sort.Slice(vlan.Ips, func(i, j int) bool {
|
||||
return vlan.Ips[i] < vlan.Ips[j]
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -315,11 +315,11 @@ func (self *SCloudproviderregion) markEndSync(ctx context.Context, userCred mccl
|
||||
log.Debugf("markEndSync deepSync %v", *deepSync)
|
||||
err := self.markEndSyncInternal(userCred, syncResults, deepSync)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "markEndSyncInternal")
|
||||
}
|
||||
err = self.GetProvider().markEndSyncWithLock(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "markEndSyncWithLock")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -335,8 +335,7 @@ func (self *SCloudproviderregion) markEndSyncInternal(userCred mcclient.TokenCre
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("Failed to markEndSyncInternal error: %v", err)
|
||||
return err
|
||||
return errors.Wrapf(err, "db.Update")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -373,11 +372,18 @@ func (set SSyncResultSet) Add(manager db.IModelManager, result compare.SyncResul
|
||||
func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.TokenCredential, syncRange SSyncRange) error {
|
||||
syncResults := SSyncResultSet{}
|
||||
|
||||
self.markSyncing(userCred)
|
||||
defer self.markEndSync(ctx, userCred, syncResults, &syncRange.DeepSync)
|
||||
|
||||
localRegion := self.GetRegion()
|
||||
provider := self.GetProvider()
|
||||
|
||||
self.markSyncing(userCred)
|
||||
|
||||
defer func() {
|
||||
err := self.markEndSync(ctx, userCred, syncResults, &syncRange.DeepSync)
|
||||
if err != nil {
|
||||
log.Errorf("markEndSync for %s(%s) : %v", localRegion.Name, provider.Name, err)
|
||||
}
|
||||
}()
|
||||
|
||||
driver, err := provider.GetProvider()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get driver, connection problem?")
|
||||
@@ -425,6 +431,7 @@ func (self *SCloudproviderregion) submitSyncTask(ctx context.Context, userCred m
|
||||
self.markStartSync(userCred)
|
||||
RunSyncCloudproviderRegionTask(ctx, self.getSyncTaskKey(), func() {
|
||||
nopanic.Run(func() {
|
||||
ctx = context.WithValue(ctx, "provider-region", fmt.Sprintf("%d", self.RowId))
|
||||
err := self.DoSync(ctx, userCred, syncRange)
|
||||
if err != nil {
|
||||
log.Errorf("DoSync faild %v", err)
|
||||
@@ -480,7 +487,7 @@ func (cpr *SCloudproviderregion) needAutoSyncInternal() bool {
|
||||
region := cpr.GetRegion()
|
||||
log.Debugf("empty region %s! no need to check so frequently", region.GetName())
|
||||
}
|
||||
if time.Now().Sub(cpr.LastSyncEndAt) > time.Duration(intval)*time.Second {
|
||||
if time.Now().Sub(cpr.LastSync) > time.Duration(intval)*time.Second {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -769,8 +769,7 @@ func (self *SCloudprovider) markEndSync(userCred mcclient.TokenCredential) error
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("Failed to markEndSync error: %v", err)
|
||||
return err
|
||||
return errors.Wrapf(err, "markEndSync")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1347,7 +1346,10 @@ func (provider *SCloudprovider) syncCloudproviderRegions(ctx context.Context, us
|
||||
}
|
||||
}
|
||||
if syncCnt == 0 {
|
||||
provider.markEndSyncWithLock(ctx, userCred)
|
||||
err := provider.markEndSyncWithLock(ctx, userCred)
|
||||
if err != nil {
|
||||
log.Errorf("markEndSyncWithLock for %s error: %v", provider.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ type SSyncableBaseResourceManager struct{}
|
||||
|
||||
func (self *SSyncableBaseResource) CanSync() bool {
|
||||
if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_QUEUED || self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING {
|
||||
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > 1800*time.Second {
|
||||
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > time.Duration(options.Options.MinimalSyncIntervalSeconds)*time.Second {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@@ -518,6 +518,7 @@ func syncZoneStorages(ctx context.Context, userCred mcclient.TokenCredential, sy
|
||||
}
|
||||
|
||||
func syncStorageCaches(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localStorage *SStorage, remoteStorage cloudprovider.ICloudStorage) (cachePair sStoragecacheSyncPair) {
|
||||
log.Debugf("syncStorageCaches for storage %s", localStorage.GetId())
|
||||
remoteCache := remoteStorage.GetIStoragecache()
|
||||
if remoteCache == nil {
|
||||
log.Errorf("remote storageCache is nil")
|
||||
@@ -1277,7 +1278,7 @@ func syncOnPremiseCloudProviderInfo(
|
||||
result := storageCachePairs[i].syncCloudImages(ctx, userCred)
|
||||
syncResults.Add(StoragecachedimageManager, result)
|
||||
msg := result.Result()
|
||||
log.Infof("syncCloudImages result: %s", msg)
|
||||
log.Infof("syncCloudImages for stroagecache %s result: %s", storageCachePairs[i].local.GetId(), msg)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +298,11 @@ func (manager *SDBInstanceSkuManager) GetPropertyInstanceSpecs(ctx context.Conte
|
||||
return nil, errors.Wrap(err, "manager.ListItemFilter")
|
||||
}
|
||||
|
||||
q2, err := manager.ListItemFilter(ctx, manager.Query(), userCred, listQuery)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "manager.ListItemFilter")
|
||||
}
|
||||
|
||||
input := &SDBInstanceSku{}
|
||||
query.Unmarshal(input)
|
||||
for k, v := range map[string]interface{}{
|
||||
@@ -317,15 +322,30 @@ func (manager *SDBInstanceSkuManager) GetPropertyInstanceSpecs(ctx context.Conte
|
||||
value := v.(string)
|
||||
if len(value) > 0 {
|
||||
q = q.Equals(k, v)
|
||||
q2 = q2.Equals(k, v)
|
||||
}
|
||||
case int, int64:
|
||||
value := fmt.Sprintf("%d", v)
|
||||
if value != "0" {
|
||||
q = q.Equals(k, v)
|
||||
q2 = q2.Equals(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sq := q2.SubQuery()
|
||||
q2 = sq.Query(sq.Field("zone1"), sq.Field("zone2"), sq.Field("zone3")).Distinct()
|
||||
|
||||
skuZones := []struct {
|
||||
Zone1 string
|
||||
Zone2 string
|
||||
Zone3 string
|
||||
}{}
|
||||
err = q2.All(&skuZones)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "query sku zones")
|
||||
}
|
||||
|
||||
skus := []SDBInstanceSku{}
|
||||
q = q.GroupBy(q.Field("vcpu_count"), q.Field("vmem_size_mb"))
|
||||
q = q.Asc(q.Field("vcpu_count"), q.Field("vmem_size_mb"))
|
||||
@@ -360,23 +380,7 @@ func (manager *SDBInstanceSkuManager) GetPropertyInstanceSpecs(ctx context.Conte
|
||||
result.Zones.Zone1 = map[string]string{}
|
||||
result.Zones.Zone2 = map[string]string{}
|
||||
result.Zones.Zone3 = map[string]string{}
|
||||
for _, sku := range skus {
|
||||
if _, ok := result.cpuMemsMb[sku.VcpuCount]; !ok {
|
||||
result.cpuMemsMb[sku.VcpuCount] = map[int]bool{}
|
||||
result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)] = []int{}
|
||||
result.Cpus = append(result.Cpus, sku.VcpuCount)
|
||||
}
|
||||
|
||||
if _, ok := result.cpuMemsMb[sku.VcpuCount][sku.VmemSizeMb]; !ok {
|
||||
result.cpuMemsMb[sku.VcpuCount][sku.VmemSizeMb] = true
|
||||
result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)] = append(result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)], sku.VmemSizeMb)
|
||||
}
|
||||
|
||||
if _, ok := result.memsMb[sku.VmemSizeMb]; !ok {
|
||||
result.memsMb[sku.VmemSizeMb] = true
|
||||
result.MemsMb = append(result.MemsMb, sku.VmemSizeMb)
|
||||
}
|
||||
|
||||
for _, sku := range skuZones {
|
||||
if _, ok := result.Zones.Zone1[sku.Zone1]; !ok && len(sku.Zone1) > 0 {
|
||||
result.Zones.Zone1[sku.Zone1] = sku.Zone1
|
||||
}
|
||||
@@ -403,20 +407,36 @@ func (manager *SDBInstanceSkuManager) GetPropertyInstanceSpecs(ctx context.Conte
|
||||
result.Zones.Zones[zoneId] = zoneId
|
||||
}
|
||||
}
|
||||
|
||||
zq := ZoneManager.Query("id", "name").In("id", result.zones)
|
||||
rows, err := zq.Rows()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
id, name := "", ""
|
||||
err = rows.Scan(&id, &name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "rows.Scan")
|
||||
for _, sku := range skus {
|
||||
if _, ok := result.cpuMemsMb[sku.VcpuCount]; !ok {
|
||||
result.cpuMemsMb[sku.VcpuCount] = map[int]bool{}
|
||||
result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)] = []int{}
|
||||
result.Cpus = append(result.Cpus, sku.VcpuCount)
|
||||
}
|
||||
result.zoneNames[id] = name
|
||||
|
||||
if _, ok := result.cpuMemsMb[sku.VcpuCount][sku.VmemSizeMb]; !ok {
|
||||
result.cpuMemsMb[sku.VcpuCount][sku.VmemSizeMb] = true
|
||||
result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)] = append(result.CpuMemsMb[fmt.Sprintf("%d", sku.VcpuCount)], sku.VmemSizeMb)
|
||||
}
|
||||
|
||||
if _, ok := result.memsMb[sku.VmemSizeMb]; !ok {
|
||||
result.memsMb[sku.VmemSizeMb] = true
|
||||
result.MemsMb = append(result.MemsMb, sku.VmemSizeMb)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
zones := []struct {
|
||||
Id string
|
||||
Name string
|
||||
}{}
|
||||
|
||||
err = ZoneManager.Query("id", "name").In("id", result.zones).All(&zones)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "query zones")
|
||||
}
|
||||
for _, zone := range zones {
|
||||
result.zoneNames[zone.Id] = zone.Name
|
||||
}
|
||||
|
||||
for _, zoneId := range result.Zones.Zone1 {
|
||||
|
||||
@@ -60,6 +60,7 @@ type SDiskManager struct {
|
||||
SStorageResourceBaseManager
|
||||
SBillingResourceBaseManager
|
||||
db.SMultiArchResourceBaseManager
|
||||
db.SAutoDeleteResourceBaseManager
|
||||
}
|
||||
|
||||
var DiskManager *SDiskManager
|
||||
@@ -83,6 +84,7 @@ type SDisk struct {
|
||||
SBillingResourceBase
|
||||
SStorageResourceBase `width:"128" charset:"ascii" nullable:"true" list:"admin" create:"optional"`
|
||||
db.SMultiArchResourceBase
|
||||
db.SAutoDeleteResourceBase
|
||||
|
||||
// 磁盘存储类型
|
||||
// example: qcow2
|
||||
@@ -93,10 +95,6 @@ type SDisk struct {
|
||||
// 磁盘路径
|
||||
AccessPath string `width:"256" charset:"ascii" nullable:"true" get:"user" json:"access_path"`
|
||||
|
||||
// 是否跟随云主机自动删除, 仅绑定到云主机时才生效
|
||||
// example: false
|
||||
AutoDelete bool `nullable:"false" default:"false" get:"user" update:"user" json:"auto_delete"`
|
||||
|
||||
// 存储Id
|
||||
// StorageId string `width:"128" charset:"ascii" nullable:"true" list:"admin" create:"optional"`
|
||||
|
||||
@@ -174,6 +172,11 @@ func (manager *SDiskManager) ListItemFilter(
|
||||
return nil, errors.Wrap(err, "SMultiArchResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
|
||||
q, err = manager.SAutoDeleteResourceBaseManager.ListItemFilter(ctx, q, userCred, query.AutoDeleteResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "SAutoDeleteResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
|
||||
if query.Unused != nil {
|
||||
guestdisks := GuestdiskManager.Query().SubQuery()
|
||||
sq := guestdisks.Query(guestdisks.Field("disk_id"))
|
||||
@@ -224,14 +227,6 @@ func (manager *SDiskManager) ListItemFilter(
|
||||
q = q.Equals("disk_size", query.DiskSize)
|
||||
}
|
||||
|
||||
if query.AutoDelete != nil {
|
||||
if *query.AutoDelete {
|
||||
q = q.IsTrue("auto_delete")
|
||||
} else {
|
||||
q = q.IsFalse("auto_delete")
|
||||
}
|
||||
}
|
||||
|
||||
if len(query.FsFormat) > 0 {
|
||||
q = q.Equals("fs_format", query.FsFormat)
|
||||
}
|
||||
@@ -1736,7 +1731,9 @@ func fillDiskConfigByImage(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
diskConfig.SizeMb = image.MinDiskMB // MB
|
||||
}
|
||||
if strings.Contains(image.Properties["os_arch"], "aarch") {
|
||||
diskConfig.OsArch = api.OS_ARCH_ARM
|
||||
diskConfig.OsArch = apis.OS_ARCH_AARCH64
|
||||
} else {
|
||||
diskConfig.OsArch = image.Properties["os_arch"]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -197,7 +197,7 @@ func (self *SGuest) PerformSaveImage(ctx context.Context, userCred mcclient.Toke
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.OS_ARCH_ARM {
|
||||
if apis.IsARM(self.OsArch) {
|
||||
var osArch string
|
||||
if osArch = self.GetMetadata("os_arch", nil); len(osArch) == 0 {
|
||||
host := self.GetHost()
|
||||
@@ -272,7 +272,7 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.OS_ARCH_ARM {
|
||||
if apis.IsARM(self.OsArch) {
|
||||
var osArch string
|
||||
if osArch = self.GetMetadata("os_arch", nil); len(osArch) == 0 {
|
||||
host := self.GetHost()
|
||||
@@ -729,10 +729,11 @@ func (self *SGuest) PerformAttachdisk(ctx context.Context, userCred mcclient.Tok
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartSyncTask(ctx context.Context, userCred mcclient.TokenCredential, fwOnly bool, parentTaskId string) error {
|
||||
func (self *SGuest) StartSyncTask(ctx context.Context, userCred mcclient.TokenCredential, firewallOnly bool,
|
||||
parentTaskId string) error {
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
if fwOnly {
|
||||
if firewallOnly {
|
||||
data.Add(jsonutils.JSONTrue, "fw_only")
|
||||
} else if err := self.SetStatus(userCred, api.VM_SYNC_CONFIG, ""); err != nil {
|
||||
log.Errorln(err)
|
||||
@@ -1086,24 +1087,17 @@ func (self *SGuest) StartSyncstatus(ctx context.Context, userCred mcclient.Token
|
||||
|
||||
func (self *SGuest) StartAutoDeleteGuestTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
db.OpsLog.LogEvent(self, db.ACT_DELETE, "auto-delete after stop", userCred)
|
||||
return self.StartDeleteGuestTask(ctx, userCred, parentTaskId, false, false, false)
|
||||
opts := api.ServerDeleteInput{}
|
||||
return self.StartDeleteGuestTask(ctx, userCred, parentTaskId, opts)
|
||||
}
|
||||
|
||||
func (self *SGuest) StartDeleteGuestTask(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string,
|
||||
isPurge, overridePendingDelete, deleteSnapshots bool,
|
||||
opts api.ServerDeleteInput,
|
||||
) error {
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(self.Status), "guest_status")
|
||||
if isPurge {
|
||||
params.Add(jsonutils.JSONTrue, "purge")
|
||||
}
|
||||
if overridePendingDelete {
|
||||
params.Add(jsonutils.JSONTrue, "override_pending_delete")
|
||||
}
|
||||
if deleteSnapshots {
|
||||
params.Add(jsonutils.JSONTrue, "delete_snapshots")
|
||||
}
|
||||
params.Update(jsonutils.Marshal(opts))
|
||||
self.SetStatus(userCred, api.VM_START_DELETE, "")
|
||||
return self.GetDriver().StartDeleteGuestTask(ctx, userCred, self, params, parentTaskId)
|
||||
}
|
||||
@@ -1400,7 +1394,10 @@ func (self *SGuest) PerformPurge(ctx context.Context, userCred mcclient.TokenCre
|
||||
if host != nil && host.GetEnabled() {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot purge server on enabled host")
|
||||
}
|
||||
err = self.StartDeleteGuestTask(ctx, userCred, "", true, false, false)
|
||||
opts := api.ServerDeleteInput{
|
||||
Purge: true,
|
||||
}
|
||||
err = self.StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2903,14 +2900,11 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eip, err := self.GetEipOrPublicIp()
|
||||
err = self.IsEipAssociable()
|
||||
if err != nil {
|
||||
log.Errorf("Fail to get Eip %s", err)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
if eip != nil {
|
||||
return nil, httperrors.NewInvalidStatusError("already associate with eip")
|
||||
}
|
||||
|
||||
eipStr := input.EipId
|
||||
if len(eipStr) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("eip_id")
|
||||
@@ -2924,7 +2918,7 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
}
|
||||
|
||||
eip = eipObj.(*SElasticip)
|
||||
eip := eipObj.(*SElasticip)
|
||||
eipRegion := eip.GetRegion()
|
||||
instRegion := self.getRegion()
|
||||
|
||||
@@ -4357,7 +4351,15 @@ func (guest *SGuest) PerformChangeOwner(ctx context.Context, userCred mcclient.T
|
||||
return nil, errors.Wrapf(err, "unable to change owner for instance snapshot %s", isps[i].GetId())
|
||||
}
|
||||
}
|
||||
return guest.SVirtualResourceBase.PerformChangeOwner(ctx, userCred, query, input)
|
||||
changOwner, err := guest.SVirtualResourceBase.PerformChangeOwner(ctx, userCred, query, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = guest.StartSyncTask(ctx, userCred, false, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "PerformChangeOwner StartSyncTask err")
|
||||
}
|
||||
return changOwner, nil
|
||||
}
|
||||
|
||||
func (guest *SGuest) AllowPerformResizeDisk(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
|
||||
@@ -199,7 +199,7 @@ func (gtm *SGuestTemplateManager) validateContent(ctx context.Context, userCred
|
||||
}
|
||||
// check Image
|
||||
imageId := input.Disks[0].ImageId
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageId, true)
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageId, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "getImageInfo of '%s'", imageId)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ type IGuestDriver interface {
|
||||
RemoteDeployGuestForRebuildRoot(ctx context.Context, guest *SGuest, ihost cloudprovider.ICloudHost, task taskman.ITask, desc cloudprovider.SManagedVMCreateConfig) (jsonutils.JSONObject, error)
|
||||
GetGuestInitialStateAfterCreate() string
|
||||
GetGuestInitialStateAfterRebuild() string
|
||||
GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string
|
||||
GetDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string
|
||||
GetInstanceCapability() cloudprovider.SInstanceCapability
|
||||
|
||||
OnGuestDeployTaskDataReceived(ctx context.Context, guest *SGuest, task taskman.ITask, data jsonutils.JSONObject) error
|
||||
|
||||
@@ -296,6 +296,13 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
lockman.LockObject(ctx, network)
|
||||
defer lockman.ReleaseObject(ctx, network)
|
||||
|
||||
vpc := network.GetVpc()
|
||||
if vpc == nil {
|
||||
return nil, fmt.Errorf("cannot find vpc of network %s(%s)", network.Id, network.Name)
|
||||
}
|
||||
|
||||
provider := vpc.GetProviderName()
|
||||
|
||||
macAddr, err := manager.GenerateMac(network.Id, mac)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -317,7 +324,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
// if reuse Ip address, no need to check address availability
|
||||
// assign it anyway
|
||||
gn.IpAddr = address
|
||||
} else {
|
||||
} else if provider == api.CLOUD_PROVIDER_ONECLOUD || options.Options.EnablePreAllocateIpAddr {
|
||||
addrTable := network.GetUsedAddresses()
|
||||
recentAddrTable := manager.getRecentlyReleasedIPAddresses(network.Id, network.getAllocTimoutDuration())
|
||||
ipAddr, err := network.GetFreeIP(ctx, userCred, addrTable, recentAddrTable, address, allocDir, reserved)
|
||||
@@ -330,9 +337,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
gn.IpAddr = ipAddr
|
||||
}
|
||||
|
||||
if vpc := network.GetVpc(); vpc == nil {
|
||||
return nil, fmt.Errorf("cannot find vpc of network %s(%s)", network.Id, network.Name)
|
||||
} else if vpc.Id != api.DEFAULT_VPC_ID && vpc.GetProviderName() == api.CLOUD_PROVIDER_ONECLOUD {
|
||||
if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD {
|
||||
var err error
|
||||
GuestnetworkManager.lockAllocMappedAddr(ctx)
|
||||
defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
|
||||
@@ -817,11 +822,11 @@ func (self *SGuestnetwork) getMtu(net *SNetwork) int {
|
||||
}
|
||||
|
||||
func (self *SGuestnetwork) IsAllocated() bool {
|
||||
if regutils.MatchMacAddr(self.MacAddr) && (self.Virtual || regutils.MatchIP4Addr(self.IpAddr)) {
|
||||
provider := self.GetGuest().getRegion().Provider
|
||||
if regutils.MatchMacAddr(self.MacAddr) && (self.Virtual || regutils.MatchIP4Addr(self.IpAddr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetIPTenantIdPairs() {
|
||||
|
||||
@@ -585,15 +585,20 @@ func (manager *SGuestManager) OrderByExtraFields(ctx context.Context, q *sqlchem
|
||||
return nil, errors.Wrap(err, "SNetworkResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
}
|
||||
//fields = manager.SDiskResourceBaseManager.GetOrderByFields(query.DiskFilterListInput)
|
||||
//if db.NeedOrderQuery(fields) {
|
||||
// diskQ := GuestdiskManager.Query("guest_id", "disk_id").SubQuery()
|
||||
// q = q.LeftJoin(diskQ, sqlchemy.Equals(q.Field("id"), diskQ.Field("guest_id"))).Distinct()
|
||||
// q, err = manager.SDiskResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.DiskFilterListInput)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "SDiskResourceBaseManager.OrderByExtraFields")
|
||||
// }
|
||||
//}
|
||||
|
||||
if db.NeedOrderQuery([]string{query.OrderByDisk}) {
|
||||
guestdisks := GuestdiskManager.Query().SubQuery()
|
||||
disks := DiskManager.Query().SubQuery()
|
||||
guestdiskQ := guestdisks.Query(
|
||||
guestdisks.Field("guest_id"),
|
||||
sqlchemy.SUM("disks_size", disks.Field("disk_size")),
|
||||
)
|
||||
guestdiskQ = guestdiskQ.LeftJoin(disks, sqlchemy.Equals(guestdiskQ.Field("disk_id"), disks.Field("id")))
|
||||
guestdiskSQ := guestdiskQ.GroupBy(guestdiskQ.Field("guest_id")).SubQuery()
|
||||
|
||||
q = q.LeftJoin(guestdiskSQ, sqlchemy.Equals(q.Field("id"), guestdiskSQ.Field("guest_id")))
|
||||
db.OrderByFields(q, []string{query.OrderByDisk}, []sqlchemy.IQueryField{guestdiskSQ.Field("disks_size")})
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
@@ -1214,7 +1219,7 @@ func (manager *SGuestManager) validateCreateData(
|
||||
}
|
||||
|
||||
if arch := imgProperties["os_arch"]; strings.Contains(arch, "aarch") {
|
||||
input.OsArch = api.OS_ARCH_ARM
|
||||
input.OsArch = apis.OS_ARCH_AARCH64
|
||||
}
|
||||
|
||||
if len(imgProperties) == 0 {
|
||||
@@ -2676,8 +2681,9 @@ func (manager *SGuestManager) TotalCount(
|
||||
status []string, hypervisors []string,
|
||||
includeSystem bool, pendingDelete bool,
|
||||
hostTypes []string, resourceTypes []string, providers []string, brands []string, cloudEnv string,
|
||||
since *time.Time,
|
||||
) SGuestCountStat {
|
||||
return usageTotalGuestResouceCount(scope, ownerId, rangeObjs, status, hypervisors, includeSystem, pendingDelete, hostTypes, resourceTypes, providers, brands, cloudEnv)
|
||||
return usageTotalGuestResouceCount(scope, ownerId, rangeObjs, status, hypervisors, includeSystem, pendingDelete, hostTypes, resourceTypes, providers, brands, cloudEnv, since)
|
||||
}
|
||||
|
||||
func (self *SGuest) detachNetworks(ctx context.Context, userCred mcclient.TokenCredential, gns []SGuestnetwork, reserve bool, deploy bool) error {
|
||||
@@ -3016,9 +3022,15 @@ func (self *SGuest) SyncVMNics(ctx context.Context, userCred mcclient.TokenCrede
|
||||
if len(guestnics[i].IpAddr) > 0 && guestnics[i].IpAddr == vnics[i].GetIP() {
|
||||
// mac changed
|
||||
reserve = true
|
||||
removed = append(removed, sRemoveGuestnic{nic: &guestnics[i], reserve: reserve})
|
||||
adds = append(adds, sAddGuestnic{index: i, nic: vnics[i], net: localNet, reserve: reserve})
|
||||
} else if len(guestnics[i].IpAddr) == 0 {
|
||||
db.Update(&guestnics[i], func() error {
|
||||
guestnics[i].IpAddr = vnics[i].GetIP()
|
||||
guestnics[i].MacAddr = vnics[i].GetMAC()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
removed = append(removed, sRemoveGuestnic{nic: &guestnics[i], reserve: reserve})
|
||||
adds = append(adds, sAddGuestnic{index: i, nic: vnics[i], net: localNet, reserve: reserve})
|
||||
}
|
||||
} else {
|
||||
removed = append(removed, sRemoveGuestnic{nic: &guestnics[i]})
|
||||
@@ -3082,7 +3094,7 @@ func (self *SGuest) SyncVMNics(ctx context.Context, userCred mcclient.TokenCrede
|
||||
TryReserved: true,
|
||||
AllocDir: api.IPAllocationDefault,
|
||||
RequireDesignatedIP: true,
|
||||
UseDesignatedIP: false,
|
||||
UseDesignatedIP: true,
|
||||
NicConfs: []SNicConfig{nicConf},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -3286,9 +3298,10 @@ func usageTotalGuestResouceCount(
|
||||
hostTypes []string,
|
||||
resourceTypes []string,
|
||||
providers []string, brands []string, cloudEnv string,
|
||||
since *time.Time,
|
||||
) SGuestCountStat {
|
||||
q, guests := _guestResourceCountQuery(scope, ownerId, rangeObjs, status, hypervisors,
|
||||
pendingDelete, hostTypes, resourceTypes, providers, brands, cloudEnv)
|
||||
pendingDelete, hostTypes, resourceTypes, providers, brands, cloudEnv, since)
|
||||
if !includeSystem {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsNull(guests.Field("is_system")), sqlchemy.IsFalse(guests.Field("is_system"))))
|
||||
@@ -3316,6 +3329,7 @@ func _guestResourceCountQuery(
|
||||
hostTypes []string,
|
||||
resourceTypes []string,
|
||||
providers []string, brands []string, cloudEnv string,
|
||||
since *time.Time,
|
||||
) (*sqlchemy.SQuery, *sqlchemy.SSubQuery) {
|
||||
|
||||
guestdisks := GuestdiskManager.Query().SubQuery()
|
||||
@@ -3342,7 +3356,12 @@ func _guestResourceCountQuery(
|
||||
|
||||
isoDevSubQuery := isoDevQuery.SubQuery()
|
||||
|
||||
guests := GuestManager.Query().SubQuery()
|
||||
var guests *sqlchemy.SSubQuery
|
||||
if since != nil && !since.IsZero() {
|
||||
guests = GuestManager.RawQuery().SubQuery()
|
||||
} else {
|
||||
guests = GuestManager.Query().SubQuery()
|
||||
}
|
||||
guestBackupSubQuery := GuestManager.Query(
|
||||
"id",
|
||||
"vcpu_count",
|
||||
@@ -3391,6 +3410,11 @@ func _guestResourceCountQuery(
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(guests.Field("pending_deleted")), sqlchemy.IsFalse(guests.Field("pending_deleted"))))
|
||||
}
|
||||
|
||||
if since != nil && !since.IsZero() {
|
||||
q = q.Filter(sqlchemy.GT(guests.Field("created_at"), *since))
|
||||
}
|
||||
|
||||
return q, guests
|
||||
}
|
||||
|
||||
@@ -3817,18 +3841,9 @@ func (self *SGuest) AllowDeleteItem(ctx context.Context, userCred mcclient.Token
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowDelete(userCred, self)
|
||||
}
|
||||
|
||||
func (self *SGuest) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
var (
|
||||
overridePendingDelete = false
|
||||
purge = false
|
||||
deleteSnapshots = false
|
||||
)
|
||||
if query != nil {
|
||||
overridePendingDelete = jsonutils.QueryBoolean(query, "override_pending_delete", false)
|
||||
purge = jsonutils.QueryBoolean(query, "purge", false)
|
||||
deleteSnapshots = jsonutils.QueryBoolean(query, "delete_snapshots", false)
|
||||
}
|
||||
return self.StartDeleteGuestTask(ctx, userCred, "", purge, overridePendingDelete, deleteSnapshots)
|
||||
// 删除虚拟机
|
||||
func (self *SGuest) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query api.ServerDeleteInput, data jsonutils.JSONObject) error {
|
||||
return self.StartDeleteGuestTask(ctx, userCred, "", query)
|
||||
}
|
||||
|
||||
func (self *SGuest) DeleteAllDisksInDB(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
@@ -4638,7 +4653,10 @@ func (manager *SGuestManager) CleanPendingDeleteServers(ctx context.Context, use
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(guests); i += 1 {
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", false, true, false)
|
||||
opts := api.ServerDeleteInput{
|
||||
OverridePendingDelete: true,
|
||||
}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4709,7 +4727,7 @@ func (manager *SGuestManager) DeleteExpiredPrepaidServers(ctx context.Context, u
|
||||
if guests == nil {
|
||||
return
|
||||
}
|
||||
deteleSnapshot := options.Options.DeleteSnapshotExpiredRelease
|
||||
deleteSnapshot := options.Options.DeleteSnapshotExpiredRelease
|
||||
for i := 0; i < len(guests); i += 1 {
|
||||
// fake delete expired prepaid servers
|
||||
if len(guests[i].ExternalId) > 0 {
|
||||
@@ -4719,7 +4737,10 @@ func (manager *SGuestManager) DeleteExpiredPrepaidServers(ctx context.Context, u
|
||||
}
|
||||
}
|
||||
guests[i].SetDisableDelete(userCred, false)
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", false, false, deteleSnapshot)
|
||||
opts := api.ServerDeleteInput{
|
||||
DeleteSnapshots: deleteSnapshot,
|
||||
}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4755,7 +4776,8 @@ func (manager *SGuestManager) DeleteExpiredPostpaidServers(ctx context.Context,
|
||||
}
|
||||
}
|
||||
guests[i].SetDisableDelete(userCred, false)
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", false, false, deleteSnapshot)
|
||||
opts := api.ServerDeleteInput{DeleteSnapshots: deleteSnapshot}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4868,6 +4890,28 @@ func (self *SGuest) isInReconcile(userCred mcclient.TokenCredential) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SGuest) IsEipAssociable() error {
|
||||
var eip *SElasticip
|
||||
var err error
|
||||
switch self.Hypervisor {
|
||||
case api.HYPERVISOR_AWS:
|
||||
eip, err = self.GetElasticIp()
|
||||
default:
|
||||
eip, err = self.GetEipOrPublicIp()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Fail to get Eip %s", err)
|
||||
return errors.Wrap(err, "IsEipAssociable")
|
||||
}
|
||||
|
||||
if eip != nil {
|
||||
return httperrors.NewInvalidStatusError("already associate with eip")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) GetEipOrPublicIp() (*SElasticip, error) {
|
||||
return ElasticipManager.getEip(api.EIP_ASSOCIATE_TYPE_SERVER, self.Id, "")
|
||||
}
|
||||
@@ -4883,10 +4927,16 @@ func (self *SGuest) GetPublicIp() (*SElasticip, error) {
|
||||
func (self *SGuest) SyncVMEip(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extEip cloudprovider.ICloudEIP, syncOwnerId mcclient.IIdentityProvider) compare.SyncResult {
|
||||
result := compare.SyncResult{}
|
||||
|
||||
eip, err := self.GetEipOrPublicIp()
|
||||
eip, err := self.GetPublicIp()
|
||||
if err != nil {
|
||||
result.Error(fmt.Errorf("getEip error %s", err))
|
||||
result.Error(fmt.Errorf("getPublicIp error %s", err))
|
||||
return result
|
||||
} else if eip == nil {
|
||||
eip, err = self.GetElasticIp()
|
||||
if err != nil {
|
||||
result.Error(fmt.Errorf("getEip error %s", err))
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
if eip == nil && extEip == nil {
|
||||
|
||||
@@ -90,7 +90,10 @@ func (self *SGuest) DoPerformPrepaidRecycle(ctx context.Context, userCred mcclie
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_RECYCLE_PREPAID, self.GetShortDesc(ctx), userCred, true)
|
||||
|
||||
if autoDelete {
|
||||
self.StartDeleteGuestTask(ctx, userCred, "", false, true, false)
|
||||
opts := api.ServerDeleteInput{
|
||||
OverridePendingDelete: true,
|
||||
}
|
||||
self.StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -62,6 +62,7 @@ type IHostDriver interface {
|
||||
ValidateAttachStorage(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, storage *SStorage, data *jsonutils.JSONDict) error
|
||||
RequestAttachStorage(ctx context.Context, hoststorage *SHoststorage, host *SHost, storage *SStorage, task taskman.ITask) error
|
||||
RequestDetachStorage(ctx context.Context, host *SHost, storage *SStorage, task taskman.ITask) error
|
||||
RequestSyncOnHost(ctx context.Context, host *SHost, task taskman.ITask) error
|
||||
}
|
||||
|
||||
var hostDrivers map[string]IHostDriver
|
||||
|
||||
@@ -540,7 +540,7 @@ func (manager *SHostManager) CustomizeFilterList(ctx context.Context, q *sqlchem
|
||||
}
|
||||
|
||||
func (self *SHost) IsArmHost() bool {
|
||||
return self.CpuArchitecture == api.CPU_ARCH_AARCH64
|
||||
return self.CpuArchitecture == apis.OS_ARCH_AARCH64
|
||||
}
|
||||
|
||||
func (self *SHost) GetZone() *SZone {
|
||||
@@ -3971,7 +3971,7 @@ func (self *SHost) AllowPerformIpmiProbe(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SHost) PerformIpmiProbe(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if utils.IsInStringArray(self.Status, []string{api.BAREMETAL_INIT, api.BAREMETAL_READY, api.BAREMETAL_RUNNING}) {
|
||||
if utils.IsInStringArray(self.Status, []string{api.BAREMETAL_INIT, api.BAREMETAL_READY, api.BAREMETAL_RUNNING, api.BAREMETAL_PROBE_FAIL, api.BAREMETAL_UNKNOWN}) {
|
||||
return nil, self.StartIpmiProbeTask(ctx, userCred, "")
|
||||
}
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot do Ipmi-probe in status %s", self.Status)
|
||||
@@ -5634,10 +5634,24 @@ func (host *SHost) PerformChangeOwner(ctx context.Context, userCred mcclient.Tok
|
||||
return nil, errors.Wrap(err, "local storage change owner")
|
||||
}
|
||||
}
|
||||
|
||||
err = host.StartSyncTask(ctx, userCred, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "PerformChangeOwner StartSyncTask err")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SHost) StartSyncTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
if task, err := taskman.TaskManager.NewTask(ctx, "HostSyncTask", self, userCred, jsonutils.NewDict(), parentTaskId, "",
|
||||
nil); err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (host *SHost) GetChangeOwnerRequiredDomainIds() []string {
|
||||
requires := stringutils2.SSortedStrings{}
|
||||
guests, _ := host.GetGuests()
|
||||
|
||||
@@ -31,11 +31,10 @@ func (man *SI18nResourceBaseManager) SyncI18ns(ctx context.Context, userCred mcc
|
||||
itable := man.getSModelI18nTable(model, table)
|
||||
_, _, r := db.I18nManager.SyncI18ns(ctx, userCred, model, itable)
|
||||
if r.IsError() {
|
||||
log.Infof("SyncI18ns for %s %s result: %s", model.Keyword(), model.GetId(), r.Result())
|
||||
log.Errorf("SyncI18ns for %s %s result: %s", model.Keyword(), model.GetId(), r.Result())
|
||||
return errors.Wrap(r.AllError(), "SyncI18ns")
|
||||
}
|
||||
|
||||
log.Debugf("SyncI18ns for %s %s result: %s", model.Keyword(), model.GetId(), r.Result())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -51,7 +50,7 @@ func (self *SI18nResourceBase) RemoveI18ns(ctx context.Context, userCred mcclien
|
||||
func (self *SI18nResourceBase) GetModelI18N(ctx context.Context, model db.IModel) *jsonutils.JSONDict {
|
||||
entries, err := db.I18nManager.GetModelI18N(ctx, model)
|
||||
if err != nil {
|
||||
log.Infof("GetI18N %s", err)
|
||||
log.Errorf("GetModelI18N error %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,7 +65,7 @@ func (self *SI18nResourceBase) GetModelI18N(ctx context.Context, model db.IModel
|
||||
func (self *SI18nResourceBase) GetModelKeyI18N(ctx context.Context, model db.IModel, keyName string) (string, bool) {
|
||||
entries, err := db.I18nManager.GetModelKeyI18N(ctx, model, keyName)
|
||||
if err != nil {
|
||||
log.Infof("GetModelKeyI18N %s", err)
|
||||
log.Errorf("GetModelKeyI18N error %s", err)
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ func (manager *SInterVpcNetworkManager) newFromCloudInterVpcNetwork(ctx context.
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrapf(err, "vpc.FetchByExternalIdAndManagerId(%s)", externalVpcIds[i])
|
||||
}
|
||||
continue
|
||||
}
|
||||
vpcIds = append(vpcIds, vpc.GetId())
|
||||
}
|
||||
|
||||
@@ -816,13 +816,8 @@ func (lblis *SLoadbalancerListener) GetLoadbalancerCertificate() (*SCachedLoadba
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
region := lblis.GetRegion()
|
||||
if region == nil {
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "loadbalancer listener is not attached to any region")
|
||||
}
|
||||
|
||||
ret := &SCachedLoadbalancerCertificate{}
|
||||
err := CachedLoadbalancerCertificateManager.Query().Equals("id", lblis.CachedCertificateId).Equals("cloudregion_id", region.Id).IsFalse("pending_deleted").First(ret)
|
||||
err := CachedLoadbalancerCertificateManager.Query().Equals("id", lblis.CachedCertificateId).IsFalse("pending_deleted").First(ret)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
|
||||
@@ -916,7 +916,7 @@ func (manager *SNetworkManager) TotalPortCount(
|
||||
userCred mcclient.IIdentityProvider,
|
||||
providers []string, brands []string, cloudEnv string,
|
||||
rangeObjs []db.IStandaloneModel,
|
||||
) NetworkPortStat {
|
||||
) map[string]NetworkPortStat {
|
||||
nets := make([]SNetwork, 0)
|
||||
err := manager.totalPortCountQ(
|
||||
scope,
|
||||
@@ -927,17 +927,32 @@ func (manager *SNetworkManager) TotalPortCount(
|
||||
if err != nil {
|
||||
log.Errorf("TotalPortCount: %v", err)
|
||||
}
|
||||
ct := 0
|
||||
ctExt := 0
|
||||
ret := make(map[string]NetworkPortStat)
|
||||
for _, net := range nets {
|
||||
var stat NetworkPortStat
|
||||
var allStat NetworkPortStat
|
||||
if len(net.ServerType) > 0 {
|
||||
stat, _ = ret[net.ServerType]
|
||||
}
|
||||
allStat, _ = ret[""]
|
||||
count := net.getIPRange().AddressCount()
|
||||
if net.IsExitNetwork() {
|
||||
ctExt += count
|
||||
if len(net.ServerType) > 0 {
|
||||
stat.CountExt += count
|
||||
}
|
||||
allStat.CountExt += count
|
||||
} else {
|
||||
ct += count
|
||||
if len(net.ServerType) > 0 {
|
||||
stat.Count += count
|
||||
}
|
||||
allStat.Count += count
|
||||
}
|
||||
if len(net.ServerType) > 0 {
|
||||
ret[net.ServerType] = stat
|
||||
}
|
||||
ret[""] = allStat
|
||||
}
|
||||
return NetworkPortStat{Count: ct, CountExt: ctExt}
|
||||
return ret
|
||||
}
|
||||
|
||||
type SNicConfig struct {
|
||||
@@ -1228,6 +1243,10 @@ func (self *SNetwork) ensureIfnameHint() {
|
||||
log.Infof("network %s(%s): initialized ifname hint: %s", self.Name, self.Id, hint)
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) NewIfnameHint(hint string) (string, error) {
|
||||
return manager.newIfnameHint(hint)
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) newIfnameHint(hint string) (string, error) {
|
||||
isa := func(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
||||
|
||||
@@ -126,6 +126,7 @@ func (guest *SGuest) purge(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
guest.DetachAllNetworks(ctx, userCred)
|
||||
guest.EjectIso(userCred)
|
||||
guest.DeleteEip(ctx, userCred)
|
||||
guest.purgeInstanceSnapshots(ctx, userCred)
|
||||
guest.DeleteAllDisksInDB(ctx, userCred)
|
||||
if !utils.IsInStringArray(guest.Hypervisor, HypervisorIndependentInstanceSnapshot) {
|
||||
guest.DeleteAllInstanceSnapshotInDB(ctx, userCred)
|
||||
@@ -138,6 +139,30 @@ func (guest *SGuest) purge(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
return guest.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (guest *SGuest) purgeInstanceSnapshots(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, guest)
|
||||
defer lockman.ReleaseObject(ctx, guest)
|
||||
|
||||
iss, err := guest.GetInstanceSnapshots()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to GetInstanceSnapshots")
|
||||
}
|
||||
for i := range iss {
|
||||
err := iss[i].purge(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to purge InstanceSnapshot %s", iss[i].Id)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (is *SInstanceSnapshot) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, is)
|
||||
defer lockman.ReleaseObject(ctx, is)
|
||||
|
||||
return is.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (storage *SStorage) purgeDisks(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, storage)
|
||||
defer lockman.ReleaseObject(ctx, storage)
|
||||
|
||||
@@ -188,7 +188,7 @@ func (self *SQuota) FetchUsage(ctx context.Context) error {
|
||||
|
||||
diskSize := totalDiskSize(scope, ownerId, tristate.None, tristate.None, false, false, rangeObjs, providers, brands, keys.CloudEnv, hypervisors)
|
||||
|
||||
guest := usageTotalGuestResouceCount(scope, ownerId, rangeObjs, nil, hypervisors, false, false, nil, nil, providers, brands, keys.CloudEnv)
|
||||
guest := usageTotalGuestResouceCount(scope, ownerId, rangeObjs, nil, hypervisors, false, false, nil, nil, providers, brands, keys.CloudEnv, nil)
|
||||
|
||||
self.Count = guest.TotalGuestCount
|
||||
self.Cpu = guest.TotalCpuCount
|
||||
|
||||
@@ -48,6 +48,14 @@ type SScheduledTaskLabel struct {
|
||||
Label string `width:"64" charset:"utf8" nullable:"false" index:"true"`
|
||||
}
|
||||
|
||||
func (slm *SScheduledTaskLabelManager) GetMasterFieldName() string {
|
||||
return "scheduled_task_id"
|
||||
}
|
||||
|
||||
func (slm *SScheduledTaskLabelManager) GetSlaveFieldName() string {
|
||||
return "label"
|
||||
}
|
||||
|
||||
func (slm *SScheduledTaskLabelManager) Attach(ctx context.Context, taskId, label string) error {
|
||||
sl := &SScheduledTaskLabel{
|
||||
ScheduledTaskId: taskId,
|
||||
|
||||
@@ -1093,6 +1093,7 @@ func (self *SServerSku) SyncWithPrivateCloudSku(ctx context.Context, userCred mc
|
||||
}
|
||||
|
||||
func (self *SServerSku) constructSku(extSku cloudprovider.ICloudSku) {
|
||||
self.ExternalId = extSku.GetGlobalId()
|
||||
self.InstanceTypeFamily = extSku.GetInstanceTypeFamily()
|
||||
self.InstanceTypeCategory = extSku.GetInstanceTypeCategory()
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -32,6 +33,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
@@ -539,3 +541,16 @@ func (manager *SSnapshotPolicyCacheManager) ListItemExportKeys(ctx context.Conte
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyCacheManager) ResourceScope() rbacutils.TRbacScope {
|
||||
return rbacutils.ScopeProject
|
||||
}
|
||||
|
||||
func (spc *SSnapshotPolicyCache) GetOwnerId() mcclient.IIdentityProvider {
|
||||
p, err := spc.GetSnapshotPolicy()
|
||||
if err != nil {
|
||||
log.Errorf("unable to get snapshotpolicy of snapshotpolicycache %s: %v", spc.GetId(), err)
|
||||
return nil
|
||||
}
|
||||
return p.GetOwnerId()
|
||||
}
|
||||
|
||||
@@ -354,6 +354,10 @@ func (self *SStoragecache) getCachedImageSize() int64 {
|
||||
}
|
||||
|
||||
func (self *SStoragecache) StartImageCacheTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, format string, isForce bool, parentTaskId string) error {
|
||||
return self.StartImageCacheTaskFromHost(ctx, userCred, imageId, format, isForce, "", parentTaskId)
|
||||
}
|
||||
|
||||
func (self *SStoragecache) StartImageCacheTaskFromHost(ctx context.Context, userCred mcclient.TokenCredential, imageId string, format string, isForce bool, srcHostId string, parentTaskId string) error {
|
||||
StoragecachedimageManager.Register(ctx, userCred, self.Id, imageId, "")
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
@@ -377,6 +381,10 @@ func (self *SStoragecache) StartImageCacheTask(ctx context.Context, userCred mcc
|
||||
if isForce {
|
||||
data.Add(jsonutils.JSONTrue, "is_force")
|
||||
}
|
||||
|
||||
if srcHostId != "" {
|
||||
data.Add(jsonutils.NewString(srcHostId), "source_host_id")
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "StorageCacheImageTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("create StorageCacheImageTask fail %s", err)
|
||||
|
||||
@@ -71,10 +71,10 @@ type SStorage struct {
|
||||
SZoneResourceBase `update:""`
|
||||
|
||||
// 容量大小,单位Mb
|
||||
Capacity int64 `nullable:"false" list:"domain" update:"domain" create:"domain_required"`
|
||||
Capacity int64 `nullable:"false" list:"user" update:"domain" create:"domain_required"`
|
||||
// 实际容量大小,单位Mb
|
||||
// we always expect actual capacity great or equal than zero, otherwise something wrong
|
||||
ActualCapacityUsed int64 `nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
|
||||
ActualCapacityUsed int64 `nullable:"true" list:"user" update:"domain" create:"domain_optional"`
|
||||
// 预留容量大小
|
||||
Reserved int64 `nullable:"true" default:"0" list:"domain" update:"domain"`
|
||||
// 存储类型
|
||||
|
||||
@@ -110,6 +110,8 @@ type ComputeOptions struct {
|
||||
ConvertEsxiDefaultTemplate string `help:"ESXI baremetal convert option"`
|
||||
ConvertKubeletDockerVolumeSize string `default:"256g" help:"Docker volume size"`
|
||||
|
||||
EnablePreAllocateIpAddr bool `help:"Enable private and public cloud private ip pre allocate, default true" default:"true"`
|
||||
|
||||
DefaultImageCacheDir string `default:"image_cache"`
|
||||
|
||||
SnapshotCreateDiskProtocol string `help:"Snapshot create disk protocol" choices:"url|fuse" default:"fuse"`
|
||||
@@ -120,9 +122,10 @@ type ComputeOptions struct {
|
||||
MinimalIpAddrReusedIntervalSeconds int `help:"Minimal seconds when a release IP address can be reallocate" default:"30"`
|
||||
|
||||
CloudSyncWorkerCount int `help:"how many current synchronization threads" default:"5"`
|
||||
CloudProviderSyncWorkerCount int `help:"how many current providers synchronize their regions, practically no limit" default:"10"`
|
||||
CloudAutoSyncIntervalSeconds int `help:"frequency to check auto sync tasks" default:"30"`
|
||||
DefaultSyncIntervalSeconds int `help:"minimal synchronization interval, default 1 minutes" default:"900"`
|
||||
MinimalSyncIntervalSeconds int `help:"minimal synchronization interval, default 1 minutes" default:"300"`
|
||||
DefaultSyncIntervalSeconds int `help:"minimal synchronization interval, default 15 minutes" default:"900"`
|
||||
MinimalSyncIntervalSeconds int `help:"minimal synchronization interval, default 30 minutes" default:"1800"`
|
||||
MaxCloudAccountErrorCount int `help:"maximal consecutive error count allow for a cloud account" default:"5"`
|
||||
|
||||
NameSyncResources []string `help:"resources that need synchronization of name"`
|
||||
@@ -136,8 +139,6 @@ type ComputeOptions struct {
|
||||
EnableHostHealthCheck bool `help:"enable host health check" default:"true"`
|
||||
HostHealthTimeout int `help:"second of wait host reconnect" default:"60"`
|
||||
|
||||
FetchEtcdServiceInfoAndUseEtcdLock bool `default:"true" help:"fetch etcd service info and use etcd lock"`
|
||||
|
||||
GuestTemplateCheckInterval int `help:"interval between two consecutive inspections of Guest Template in hour unit" default:"12"`
|
||||
|
||||
ScheduledTaskQueueSize int `help:"the maximum number of scheduled tasks that are being executed simultaneously" default:"100"`
|
||||
|
||||
@@ -1228,15 +1228,16 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateVpc(ctx context.Con
|
||||
}
|
||||
}
|
||||
|
||||
err = vpc.SyncRemoteWires(ctx, userCred)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "vpc.SyncRemoteWires")
|
||||
}
|
||||
|
||||
err = vpc.SyncWithCloudVpc(ctx, userCred, ivpc, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "vpc.SyncWithCloudVpc")
|
||||
}
|
||||
|
||||
err = vpc.SyncRemoteWires(ctx, userCred)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "vpc.SyncRemoteWires")
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -41,7 +41,7 @@ import (
|
||||
_ "yunion.io/x/onecloud/pkg/compute/policy"
|
||||
_ "yunion.io/x/onecloud/pkg/compute/regiondrivers"
|
||||
_ "yunion.io/x/onecloud/pkg/compute/storagedrivers"
|
||||
_ "yunion.io/x/onecloud/pkg/compute/tasks"
|
||||
"yunion.io/x/onecloud/pkg/compute/tasks"
|
||||
"yunion.io/x/onecloud/pkg/controller/autoscaling"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/esxi"
|
||||
@@ -70,11 +70,9 @@ func StartService() {
|
||||
log.Fatalf("unable to init esxi configs: %v", err)
|
||||
}
|
||||
|
||||
if opts.FetchEtcdServiceInfoAndUseEtcdLock {
|
||||
err := initEtcdLockOpts(opts)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
// always try to init etcd options
|
||||
if err := initEtcdLockOpts(opts); err != nil {
|
||||
log.Errorf("try to init etcd options error: %v", err)
|
||||
}
|
||||
|
||||
app := app_common.InitApp(baseOpts, true)
|
||||
@@ -88,6 +86,7 @@ func StartService() {
|
||||
setInfluxdbRetentionPolicy()
|
||||
|
||||
models.InitSyncWorkers(options.Options.CloudSyncWorkerCount)
|
||||
tasks.InitCloudproviderSyncWorkers(options.Options.CloudProviderSyncWorkerCount)
|
||||
|
||||
var (
|
||||
electObj *elect.Elect
|
||||
@@ -174,13 +173,23 @@ func initDefaultEtcdClient(opts *common_options.DBOptions) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
onKeepaliveFailure := func() {
|
||||
cli := etcd.Default()
|
||||
if opts.LockmanMethod == common_options.LockMethodEtcd {
|
||||
log.Fatalf("etcd keepalive failed and exit when lockman_method is %s", common_options.LockMethodEtcd)
|
||||
}
|
||||
if err := cli.RestartSession(); err != nil {
|
||||
log.Errorf("restart default session error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
err = etcd.InitDefaultEtcdClient(&etcd.SEtcdOptions{
|
||||
EtcdEndpoint: opts.EtcdEndpoints,
|
||||
EtcdUsername: opts.EtcdUsername,
|
||||
EtcdPassword: opts.EtcdPassword,
|
||||
EtcdEnabldSsl: opts.EtcdUseTLS,
|
||||
TLSConfig: tlsConfig,
|
||||
}, nil)
|
||||
}, onKeepaliveFailure)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init default etcd client")
|
||||
}
|
||||
@@ -197,7 +206,6 @@ func initEtcdLockOpts(opts *options.ComputeOptions) error {
|
||||
}
|
||||
if etcdEndpoint != nil {
|
||||
opts.EtcdEndpoints = []string{etcdEndpoint.Url}
|
||||
opts.LockmanMethod = common_options.LockMethodEtcd
|
||||
if len(etcdEndpoint.CertId) > 0 {
|
||||
dir, err := ioutil.TempDir("", "etcd-cluster-tls")
|
||||
if err != nil {
|
||||
|
||||
@@ -90,7 +90,8 @@ func (self *BaremetalConvertHypervisorTask) OnGuestDeployCompleteFailed(ctx cont
|
||||
guest := self.getGuest()
|
||||
guest.SetDisableDelete(self.UserCred, false)
|
||||
self.SetStage("OnGuestDeleteComplete", nil)
|
||||
guest.StartDeleteGuestTask(ctx, self.UserCred, self.GetTaskId(), false, true, false)
|
||||
opts := api.ServerDeleteInput{OverridePendingDelete: true}
|
||||
guest.StartDeleteGuestTask(ctx, self.UserCred, self.GetTaskId(), opts)
|
||||
logclient.AddActionLogWithStartable(self, baremetal, logclient.ACT_BM_CONVERT_HYPER, fmt.Sprintf("convert deploy failed: %s", body.String()), self.UserCred, false)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ func (self *BaremetalUnconvertHypervisorTask) OnInit(ctx context.Context, obj db
|
||||
if len(guests) == 1 {
|
||||
guest := guests[0]
|
||||
self.SetStage("OnGuestDeleteComplete", nil)
|
||||
guest.StartDeleteGuestTask(ctx, self.UserCred, self.GetTaskId(), false, true, false)
|
||||
opts := api.ServerDeleteInput{OverridePendingDelete: true}
|
||||
guest.StartDeleteGuestTask(ctx, self.UserCred, self.GetTaskId(), opts)
|
||||
} else {
|
||||
self.OnGuestDeleteComplete(ctx, baremetal, nil)
|
||||
}
|
||||
|
||||
@@ -34,9 +34,12 @@ type CloudProviderSyncInfoTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
syncWorker := appsrv.NewWorkerManager("CloudProviderSyncInfoTaskWorkerManager", 2, 512, true)
|
||||
var syncLocalTaskWorkerMan *appsrv.SWorkerManager
|
||||
|
||||
func InitCloudproviderSyncWorkers(count int) {
|
||||
syncWorker := appsrv.NewWorkerManager("CloudProviderSyncInfoTaskWorkerManager", count, 512, true)
|
||||
taskman.RegisterTaskAndWorker(CloudProviderSyncInfoTask{}, syncWorker)
|
||||
syncLocalTaskWorkerMan = appsrv.NewWorkerManager("CloudProviderSyncLocalTaskWorkerManager", count, 512, false)
|
||||
}
|
||||
|
||||
func getAction(params *jsonutils.JSONDict) string {
|
||||
@@ -96,11 +99,11 @@ func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderPreInfoComplete(ctx co
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNCING_HOST, "", self.UserCred)
|
||||
self.SetStage("OnSyncCloudProviderInfoComplete", nil)
|
||||
|
||||
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
|
||||
taskman.LocalTaskRunWithWorkers(self, func() (jsonutils.JSONObject, error) {
|
||||
provider.SyncCallSyncCloudproviderRegions(ctx, self.UserCred, syncRange)
|
||||
provider.SyncCallSyncCloudproviderInterVpcNetwork(ctx, self.UserCred)
|
||||
return nil, nil
|
||||
})
|
||||
}, syncLocalTaskWorkerMan)
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderPreInfoCompleteFailed(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
@@ -116,3 +119,12 @@ func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderInfoComplete(ctx conte
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, provider, getAction(self.Params), body, self.UserCred, true)
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderInfoCompleteFailed(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
provider := obj.(*models.SCloudprovider)
|
||||
// provider.MarkEndSync(self.UserCred)
|
||||
provider.CleanSchedCache()
|
||||
self.SetStageComplete(ctx, nil)
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_FAILED, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, provider, getAction(self.Params), body, self.UserCred, false)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ func (self *GuestDeleteTask) OnStartEipDissociate(ctx context.Context, guest *mo
|
||||
self.OnEipDissociateComplete(ctx, guest, nil)
|
||||
} else {
|
||||
self.SetStage("OnEipDissociateComplete", nil)
|
||||
eip.StartEipDissociateTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
autoDelete := jsonutils.QueryBoolean(self.GetParams(), "delete_eip", false)
|
||||
eip.StartEipDissociateTask(ctx, self.UserCred, autoDelete, self.GetTaskId())
|
||||
}
|
||||
} else {
|
||||
self.OnEipDissociateComplete(ctx, guest, nil)
|
||||
@@ -157,6 +158,10 @@ func (self *GuestDeleteTask) OnDiskDetachComplete(ctx context.Context, obj db.IS
|
||||
}
|
||||
// detach last detachable disk
|
||||
lastDisk := guestdisks[len(guestdisks)-1].GetDisk()
|
||||
deleteDisks := jsonutils.QueryBoolean(self.Params, "delete_disks", false)
|
||||
if deleteDisks {
|
||||
lastDisk.SetAutoDelete(lastDisk, self.GetUserCred(), true)
|
||||
}
|
||||
log.Debugf("lastDisk IsDetachable?? %v", lastDisk.IsDetachable())
|
||||
if !lastDisk.IsDetachable() {
|
||||
// no more disk need detach
|
||||
|
||||
@@ -98,7 +98,9 @@ func (self *GuestDetachScalingGroupTask) OnDetachLoadbalancerComplete(ctx contex
|
||||
}
|
||||
self.Params.Set("guest_name", jsonutils.NewString(guest.GetName()))
|
||||
self.SetStage("OnDeleteGuestComplete", nil)
|
||||
if err := guest.StartDeleteGuestTask(ctx, self.UserCred, self.Id, false, true, true); err != nil {
|
||||
opts := api.ServerDeleteInput{Purge: false, OverridePendingDelete: true, DeleteSnapshots: true}
|
||||
err := guest.StartDeleteGuestTask(ctx, self.UserCred, self.Id, opts)
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, sg, nil, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ func (self *GuestMigrateTask) SaveScheduleResult(ctx context.Context, obj ISched
|
||||
if len(disk.TemplateId) > 0 && isLocalStorage {
|
||||
targetStorageCache := targetHost.GetLocalStoragecache()
|
||||
if targetStorageCache != nil {
|
||||
err := targetStorageCache.StartImageCacheTask(
|
||||
ctx, self.UserCred, disk.TemplateId, disk.DiskFormat, false, self.GetTaskId())
|
||||
err := targetStorageCache.StartImageCacheTaskFromHost(
|
||||
ctx, self.UserCred, disk.TemplateId, disk.DiskFormat, false, guest.HostId, self.GetTaskId())
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user