mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-21 00:24:07 +08:00
Compare commits
453 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 | ||
|
|
c6433d0a09 | ||
|
|
db20a5e334 | ||
|
|
546f2fcfae | ||
|
|
b4a4cd61d9 | ||
|
|
02022c4c29 | ||
|
|
4377337a4a | ||
|
|
b9e0c22b2a | ||
|
|
d8a1e35571 | ||
|
|
13f6a0907f | ||
|
|
99dc612991 | ||
|
|
c5c00f38ba | ||
|
|
b25043be1b | ||
|
|
7de3adac3a | ||
|
|
be2e979c94 | ||
|
|
33cb189cb1 | ||
|
|
10f0e0c8bb | ||
|
|
686d314fa5 | ||
|
|
ab00f01403 | ||
|
|
fc736bc4ca | ||
|
|
a31e8734d0 | ||
|
|
53494b7764 | ||
|
|
538097ef7c | ||
|
|
6afe83e479 | ||
|
|
a7b3b1cf46 | ||
|
|
3cea602ba4 | ||
|
|
6499250b15 | ||
|
|
ace1d353b9 | ||
|
|
0285e77352 | ||
|
|
cdd209b59a | ||
|
|
9da39105fb | ||
|
|
cd4cddc34c | ||
|
|
9d1c0dbd95 | ||
|
|
006ce9dc87 | ||
|
|
6c9c8d25e9 | ||
|
|
32623f7c73 | ||
|
|
0b29451319 | ||
|
|
aae4fae0c1 | ||
|
|
0f9f2f6ee5 | ||
|
|
5cfeffcd70 | ||
|
|
6b7355a9ce | ||
|
|
f531c60e1d | ||
|
|
bfb01f5630 | ||
|
|
d7a7388431 | ||
|
|
112e7aac84 | ||
|
|
f9d1d28d85 | ||
|
|
5d7b73f21e | ||
|
|
2b2b502d64 | ||
|
|
22486c31bd | ||
|
|
9d3c44fe91 | ||
|
|
5145f1250b | ||
|
|
acd7765b33 | ||
|
|
8636a26418 | ||
|
|
84664f77cf | ||
|
|
2d53b542d3 | ||
|
|
e63a207c29 | ||
|
|
845d9a1dc0 | ||
|
|
de6ce2cd77 | ||
|
|
4032ae669d | ||
|
|
0d436306ad | ||
|
|
ec3909af50 | ||
|
|
d443279986 | ||
|
|
9088996b32 | ||
|
|
9ac72ed678 | ||
|
|
72ee6ff899 | ||
|
|
49a7ab8670 | ||
|
|
55431b87bb | ||
|
|
bc50f09483 | ||
|
|
30acf67d5c | ||
|
|
a2faac7692 | ||
|
|
5910ac16cd | ||
|
|
4f462d614c | ||
|
|
ef0387a023 | ||
|
|
31fce9fb78 | ||
|
|
f774e23248 | ||
|
|
024c14d962 | ||
|
|
b3ac1d0641 | ||
|
|
695139c04e | ||
|
|
26802d4427 | ||
|
|
b46f95ae79 | ||
|
|
7e538b255c | ||
|
|
9db72f0722 | ||
|
|
cc1b6a2d60 | ||
|
|
1411961035 | ||
|
|
33c979d227 | ||
|
|
a3621b4707 | ||
|
|
0bece9d948 | ||
|
|
14dcb91758 | ||
|
|
3d869c69bb | ||
|
|
09ef280e33 | ||
|
|
4332008c3f | ||
|
|
73c0f0350f | ||
|
|
48a894efdf | ||
|
|
fc274d5da6 | ||
|
|
e39015fa45 | ||
|
|
1bb9801666 | ||
|
|
c22c4f8ef6 | ||
|
|
5584e9af1a | ||
|
|
44e360dcdd | ||
|
|
a216ef28dd | ||
|
|
3b12892172 | ||
|
|
704cce8392 | ||
|
|
2fc04497b2 | ||
|
|
bd64be4d8a | ||
|
|
8dd1a897fc | ||
|
|
57eef5ede6 | ||
|
|
ff7fa0a520 | ||
|
|
0994e8c1ea | ||
|
|
d7dc89ccb3 | ||
|
|
8610731af3 | ||
|
|
3cc72fac65 | ||
|
|
f7e8c20f43 | ||
|
|
dbf8fde45b | ||
|
|
a6a3332e64 | ||
|
|
ca55fbd641 | ||
|
|
4ee32ef454 | ||
|
|
eeb2fcfbc8 | ||
|
|
8612095454 | ||
|
|
7612f85c6a | ||
|
|
c09c5cac79 | ||
|
|
50473268f9 | ||
|
|
010ed4f9ad | ||
|
|
eefe0aa8cb | ||
|
|
a11e5d14de | ||
|
|
a1eed47e66 | ||
|
|
50fe044cfc | ||
|
|
cdb97511c3 | ||
|
|
6be7e015d3 | ||
|
|
0eef67fafb | ||
|
|
bbb538b93d | ||
|
|
4acb2757a9 | ||
|
|
d85883780d | ||
|
|
e76abe883b | ||
|
|
a82f00aae7 | ||
|
|
1bfa27bc49 | ||
|
|
ec688fd206 | ||
|
|
20f55fe992 | ||
|
|
1fe7a54218 | ||
|
|
24bf2a163a | ||
|
|
ea4505ae55 | ||
|
|
3bcb337a4b | ||
|
|
7ee2026b21 | ||
|
|
ebe79b12d1 | ||
|
|
650ccdd7c7 | ||
|
|
68e006b71c | ||
|
|
57efd8a86b | ||
|
|
3aa83bb86d | ||
|
|
de926037dc | ||
|
|
df4f30ac47 | ||
|
|
96e443f90b | ||
|
|
dfa4d87702 | ||
|
|
4e199b84eb | ||
|
|
c17fe2df22 | ||
|
|
754d046d3a | ||
|
|
20380ae9e6 | ||
|
|
47d38a253a | ||
|
|
d366048e51 | ||
|
|
410fd2936f | ||
|
|
90e10db57c | ||
|
|
9975543ddb | ||
|
|
0c658ec53f | ||
|
|
58fb3fc9e2 | ||
|
|
f74635f3da | ||
|
|
f4972c22ba | ||
|
|
6f2bdfa22f | ||
|
|
e3d3c1f029 | ||
|
|
2fd40396c4 | ||
|
|
f416fe126c | ||
|
|
cb7956f1f1 | ||
|
|
8ca6cfa3d3 | ||
|
|
e467ef6ec7 | ||
|
|
861cd47e62 | ||
|
|
d515e5e32c | ||
|
|
71c0cc65ee | ||
|
|
86896da1f6 | ||
|
|
67082f32d3 | ||
|
|
b96b2f0b53 | ||
|
|
a8a2a248df | ||
|
|
3997f6fbe6 | ||
|
|
05efb17d35 | ||
|
|
2af9104d96 | ||
|
|
a0d99cf879 | ||
|
|
a8d550d4d8 | ||
|
|
5ccece54ac | ||
|
|
180b122167 | ||
|
|
78ba5e2fd8 | ||
|
|
9f5256c344 | ||
|
|
cdd032c711 | ||
|
|
81133a53a2 | ||
|
|
c6893892d9 | ||
|
|
8a9f3e09ea | ||
|
|
606b241b0d | ||
|
|
178a7071f0 | ||
|
|
27e5ff8635 | ||
|
|
5dc1486e7f | ||
|
|
6a50fce0ab | ||
|
|
132a00d8e0 | ||
|
|
fed6395132 | ||
|
|
7c87d73d95 | ||
|
|
a73c3c8d0e | ||
|
|
f3a567f630 | ||
|
|
5160669550 | ||
|
|
e1c5ebc29c | ||
|
|
de1553770c | ||
|
|
928c0602dd | ||
|
|
6cc34c6fb1 | ||
|
|
4885025618 | ||
|
|
68ebbbcbcc | ||
|
|
040a45aa46 | ||
|
|
299d3bed6e | ||
|
|
c4c302236f | ||
|
|
88bcb82197 | ||
|
|
80a9ed9a79 | ||
|
|
f4f973429d | ||
|
|
863a28f294 | ||
|
|
8858e7913c | ||
|
|
6254b64d5d | ||
|
|
43f8ac0027 | ||
|
|
36bd1baafe | ||
|
|
98ca80e630 | ||
|
|
a2613e6bce | ||
|
|
a8b14bb739 | ||
|
|
4850c4f8e2 | ||
|
|
64dec4254f | ||
|
|
ada90754f9 | ||
|
|
fb3456c42d | ||
|
|
cefbeb7a14 | ||
|
|
1fc01ebe94 | ||
|
|
ff0606f166 | ||
|
|
83dd534241 | ||
|
|
a7771885cf | ||
|
|
88fa743e4e | ||
|
|
0e917bb275 | ||
|
|
cd76ce27c3 | ||
|
|
114de75e7e | ||
|
|
047509ebb8 | ||
|
|
71e79e5a7b | ||
|
|
4c62508b01 | ||
|
|
e5b637906c | ||
|
|
dd7d34402f | ||
|
|
157bfb696b | ||
|
|
464e0450f9 | ||
|
|
a4b5562bd0 | ||
|
|
f0354d0c9b | ||
|
|
c3c3c00759 | ||
|
|
83adeaae4e | ||
|
|
d7f05e983f | ||
|
|
5d075bbaaf | ||
|
|
86fda0f7d0 | ||
|
|
53c8c16052 | ||
|
|
46ba9cd424 | ||
|
|
ee59f2a410 | ||
|
|
5cfbb416b3 | ||
|
|
a711f832e6 | ||
|
|
f31216be0e | ||
|
|
bc0106902a | ||
|
|
2dbfc80fac | ||
|
|
4fa95bf608 | ||
|
|
af0813cd09 | ||
|
|
3b5602e1ea | ||
|
|
e4f7d3233c | ||
|
|
287f98ac86 | ||
|
|
bb44f1cdfb | ||
|
|
644ab6f925 | ||
|
|
e775e798aa | ||
|
|
331d9d2a67 | ||
|
|
d5ed96a651 | ||
|
|
4ce85f310b | ||
|
|
3f6e669324 | ||
|
|
3f4b2163f3 | ||
|
|
78b6f85662 | ||
|
|
3124113e2f | ||
|
|
38b34239cd | ||
|
|
370b35852c | ||
|
|
f7c8bbc00b | ||
|
|
f64c6c54da | ||
|
|
c4db4bc43e | ||
|
|
1afe6ef41b |
98
Makefile
98
Makefile
@@ -6,6 +6,7 @@ ROOT_DIR := $(CURDIR)
|
||||
BUILD_DIR := $(ROOT_DIR)/_output
|
||||
BIN_DIR := $(BUILD_DIR)/bin
|
||||
BUILD_SCRIPT := $(ROOT_DIR)/build/build.sh
|
||||
DEB_BUILD_SCRIPT := $(ROOT_DIR)/build/build_deb.sh
|
||||
|
||||
ifeq ($(ONECLOUD_CI_BUILD),)
|
||||
GIT_COMMIT := $(shell git rev-parse --short HEAD)
|
||||
@@ -64,6 +65,7 @@ endif
|
||||
|
||||
cmdTargets:=$(filter-out cmd/host-image,$(wildcard cmd/*))
|
||||
rpmTargets:=$(foreach b,$(patsubst cmd/%,%,$(cmdTargets)),$(if $(shell [ -f "$(CURDIR)/build/$(b)/vars" ] && echo 1),rpm/$(b)))
|
||||
debTargets:=$(foreach b,$(patsubst cmd/%,%,$(cmdTargets)),$(if $(shell [ -f "$(CURDIR)/build/$(b)/vars" ] && echo 1),deb/$(b)))
|
||||
|
||||
all: build
|
||||
|
||||
@@ -87,21 +89,45 @@ 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)/$@
|
||||
|
||||
rpm/%: cmd/%
|
||||
$(BUILD_SCRIPT) $*
|
||||
|
||||
deb/%: cmd/%
|
||||
$(DEB_BUILD_SCRIPT) $*
|
||||
|
||||
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)
|
||||
|
||||
rpm:
|
||||
$(MAKE) $(rpmTargets)
|
||||
|
||||
deb:
|
||||
$(MAKE) $(debTargets)
|
||||
|
||||
rpmclean:
|
||||
rm -fr $(BUILD_DIR)/rpms
|
||||
|
||||
@@ -126,6 +152,11 @@ clean:
|
||||
fmt:
|
||||
@git ls-files --exclude '*' '*.go' \
|
||||
| grep -v '^vendor/' \
|
||||
| while read f; do \
|
||||
if ! grep -m1 -q '^// Code generated .* DO NOT EDIT\.$$' "$$f"; then \
|
||||
echo "$$f"; \
|
||||
fi ; \
|
||||
done \
|
||||
| xargs $(XARGS_FLAGS) gofmt -w
|
||||
|
||||
fmt-check: fmt
|
||||
@@ -198,70 +229,6 @@ mod:
|
||||
go mod tidy
|
||||
go mod vendor -v
|
||||
|
||||
|
||||
DOCKER_CENTOS_BUILD_IMAGE?=registry.cn-beijing.aliyuncs.com/yunionio/centos-build:1.1-3
|
||||
|
||||
define dockerCentOSBuildCmd
|
||||
set -o xtrace
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
cd /root/onecloud
|
||||
export GOFLAGS=-mod=vendor
|
||||
make $(1)
|
||||
chown -R $(shell id -u):$(shell id -g) _output
|
||||
endef
|
||||
|
||||
docker-centos-build: export dockerCentOSBuildCmd:=$(call dockerCentOSBuildCmd,$(F))
|
||||
docker-centos-build:
|
||||
docker rm --force onecloud-ci-build &>/dev/null || true
|
||||
docker run \
|
||||
--name onecloud-docker-centos-build \
|
||||
--rm \
|
||||
--volume $(CURDIR):/root/onecloud \
|
||||
--volume $(CURDIR)/_output/_cache:/root/.cache \
|
||||
$(DOCKER_CENTOS_BUILD_IMAGE) \
|
||||
/bin/bash -c "$$dockerCentOSBuildCmd"
|
||||
chown -R $$(id -u):$$(id -g) _output
|
||||
ls -lh _output/bin
|
||||
|
||||
# NOTE we need a way to stop and remove the container started by docker-build.
|
||||
# No --tty, --stop-signal won't work
|
||||
docker-centos-build-stop:
|
||||
docker stop --time 0 onecloud-docker-centos-build || true
|
||||
|
||||
.PHONY: docker-centos-build
|
||||
.PHONY: docker-centos-build-stop
|
||||
|
||||
DOCKER_ALPINE_BUILD_IMAGE?=registry.cn-beijing.aliyuncs.com/yunionio/alpine-build:1.0-5
|
||||
|
||||
define dockerAlpineBuildCmd
|
||||
set -o xtrace
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
cd /root/go/src/yunion.io/x/onecloud
|
||||
export GOFLAGS=-mod=vendor
|
||||
make $(1)
|
||||
chown -R $(shell id -u):$(shell id -g) _output
|
||||
endef
|
||||
|
||||
docker-alpine-build: export dockerAlpineBuildCmd:=$(call dockerAlpineBuildCmd,$(F))
|
||||
docker-alpine-build:
|
||||
docker rm --force onecloud-docker-alpine-build &>/dev/null || true
|
||||
docker run --rm \
|
||||
--name onecloud-docker-alpine-build \
|
||||
-v $(CURDIR):/root/go/src/yunion.io/x/onecloud \
|
||||
-v $(CURDIR)/_output/alpine-build:/root/go/src/yunion.io/x/onecloud/_output \
|
||||
-v $(CURDIR)/_output/alpine-build/_cache:/root/.cache \
|
||||
$(DOCKER_ALPINE_BUILD_IMAGE) \
|
||||
/bin/sh -c "$$dockerAlpineBuildCmd"
|
||||
ls -lh _output/alpine-build/bin
|
||||
|
||||
docker-alpine-build-stop:
|
||||
docker stop --time 0 onecloud-docker-alpine-build || true
|
||||
|
||||
.PHONY: docker-alpine-build
|
||||
.PHONY: docker-alpine-build-stop
|
||||
|
||||
define helpText
|
||||
Build with docker
|
||||
|
||||
@@ -321,3 +288,6 @@ image:
|
||||
|
||||
%:
|
||||
@:
|
||||
|
||||
ModName:=yunion.io/x/onecloud
|
||||
include $(CURDIR)/Makefile.common.mk
|
||||
|
||||
83
Makefile.common.mk
Normal file
83
Makefile.common.mk
Normal file
@@ -0,0 +1,83 @@
|
||||
ifeq ($(__inc_Makefile_common_mk),)
|
||||
__inc_Makefile_common_mk:=1
|
||||
|
||||
ifeq ($(ModName),)
|
||||
$(error ModName must be set, e.g. yunion.io/x/onecloud)
|
||||
endif
|
||||
ModBaseName:=$(notdir $(ModName))
|
||||
|
||||
DockerImageRegistry?=registry.cn-beijing.aliyuncs.com
|
||||
DockerImageAlpineBuild?=$(DockerImageRegistry)/yunionio/alpine-build:1.0-5
|
||||
DockerImageCentOSBuild?=$(DockerImageRegistry)/yunionio/centos-build:1.1-4
|
||||
|
||||
|
||||
EnvIf=$(if $($(1)),$(1)=$($(1)))
|
||||
|
||||
define dockerCentOSBuildCmd
|
||||
set -o xtrace
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
cd /root/go/src/yunion.io/x/$(ModBaseName)
|
||||
env \
|
||||
$(call EnvIf,GOARCH) \
|
||||
$(call EnvIf,GOOS) \
|
||||
$(call EnvIf,CGO_ENABLED) \
|
||||
make $(1)
|
||||
chown -R $(shell id -u):$(shell id -g) _output
|
||||
endef
|
||||
|
||||
docker-centos-build: export dockerCentOSBuildCmd:=$(call dockerCentOSBuildCmd,$(F))
|
||||
docker-centos-build:
|
||||
docker rm --force docker-centos-build-$(ModBaseName) &>/dev/null || true
|
||||
docker run \
|
||||
--rm \
|
||||
--name docker-centos-build-$(ModBaseName) \
|
||||
-v $(CURDIR):/root/go/src/yunion.io/x/$(ModBaseName) \
|
||||
-v $(CURDIR)/_output/centos-build:/root/go/src/yunion.io/x/$(ModBaseName)/_output \
|
||||
-v $(CURDIR)/_output/centos-build/_cache:/root/.cache \
|
||||
$(DockerImageCentOSBuild) \
|
||||
/bin/bash -c "$$dockerCentOSBuildCmd"
|
||||
ls -lh _output/centos-build/bin
|
||||
|
||||
# NOTE we need a way to stop and remove the container started by docker-build.
|
||||
# No --tty, --stop-signal won't work
|
||||
docker-centos-build-stop:
|
||||
docker stop --time 0 docker-centos-build-$(ModBaseName) || true
|
||||
|
||||
.PHONY: docker-centos-build
|
||||
.PHONY: docker-centos-build-stop
|
||||
|
||||
|
||||
define dockerAlpineBuildCmd
|
||||
set -o xtrace
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
cd /root/go/src/yunion.io/x/$(ModBaseName)
|
||||
env \
|
||||
$(call EnvIf,GOARCH) \
|
||||
$(call EnvIf,GOOS) \
|
||||
$(call EnvIf,CGO_ENABLED) \
|
||||
make $(1)
|
||||
chown -R $(shell id -u):$(shell id -g) _output
|
||||
endef
|
||||
|
||||
docker-alpine-build: export dockerAlpineBuildCmd:=$(call dockerAlpineBuildCmd,$(F))
|
||||
docker-alpine-build:
|
||||
docker rm --force docker-alpine-build-$(ModBaseName) &>/dev/null || true
|
||||
docker run \
|
||||
--rm \
|
||||
--name docker-alpine-build-$(ModBaseName) \
|
||||
-v $(CURDIR):/root/go/src/yunion.io/x/$(ModBaseName) \
|
||||
-v $(CURDIR)/_output/alpine-build:/root/go/src/yunion.io/x/$(ModBaseName)/_output \
|
||||
-v $(CURDIR)/_output/alpine-build/_cache:/root/.cache \
|
||||
$(DockerImageAlpineBuild) \
|
||||
/bin/sh -c "$$dockerAlpineBuildCmd"
|
||||
ls -lh _output/alpine-build/bin
|
||||
|
||||
docker-alpine-build-stop:
|
||||
docker stop --time 0 docker-alpine-build-$(ModBaseName) || true
|
||||
|
||||
.PHONY: docker-alpine-build
|
||||
.PHONY: docker-alpine-build-stop
|
||||
|
||||
endif # __inc_Makefile_common_mk
|
||||
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/)
|
||||
|
||||
|
||||
76
build/build_deb.sh
Executable file
76
build/build_deb.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$ROOT_DIR" ]; then
|
||||
pushd $(dirname $(readlink -f "$BASH_SOURCE")) > /dev/null
|
||||
ROOT_DIR=$(cd .. && pwd)
|
||||
popd > /dev/null
|
||||
fi
|
||||
|
||||
SRC_BIN=$ROOT_DIR/_output/bin
|
||||
SRC_BUILD=$ROOT_DIR/build
|
||||
OUTPUT_DIR=$ROOT_DIR/_output/debs
|
||||
|
||||
PKG=$1
|
||||
BIN_PATH=${2:-/opt/yunion/bin}
|
||||
|
||||
if [ -z "$PKG" ]; then
|
||||
echo "Usage: $0 <package>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BIN="$SRC_BIN/$PKG"
|
||||
ROOT="$SRC_BUILD/$PKG"
|
||||
|
||||
if [ ! -x "$BIN" ]; then
|
||||
echo "$BIN not exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "$ROOT" ]; then
|
||||
echo "$ROOT not exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. $ROOT/vars
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
TAG=$(git describe --abbrev=0 --tags || echo 000000)
|
||||
VERSION=${TAG/\//-}
|
||||
VERSION=${VERSION/v/}
|
||||
fi
|
||||
RELEASE=`date +"%y%m%d%H"`
|
||||
FULL_VERSION=$VERSION-$RELEASE
|
||||
BUILDROOT=$OUTPUT_DIR/yunion-$1-$FULL_VERSION
|
||||
rm -rf $BUILDROOT
|
||||
mkdir -p $BUILDROOT/DEBIAN
|
||||
mkdir -p $BUILDROOT/$BIN_PATH
|
||||
|
||||
cp -rf $BIN $BUILDROOT/$BIN_PATH
|
||||
cp -rf $ROOT/root/* $BUILDROOT/
|
||||
|
||||
|
||||
echo "Build root ${BUILDROOT}"
|
||||
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
CURRENT_ARCH=amd64
|
||||
;;
|
||||
aarch64)
|
||||
CURRENT_ARCH=arm64
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Package: yunion-$1
|
||||
Version: $FULL_VERSION
|
||||
Section: base
|
||||
Priority: optional
|
||||
Architecture: $CURRENT_ARCH
|
||||
Maintainer: wanyaoqi@yunionyun.com
|
||||
Description: Yunion $1
|
||||
" > $BUILDROOT/DEBIAN/control
|
||||
chmod 0755 $BUILDROOT/DEBIAN/control
|
||||
|
||||
|
||||
dpkg-deb --build $BUILDROOT
|
||||
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 {} \;
|
||||
@@ -1,3 +1,6 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/centos-build:1.1-4 as build
|
||||
RUN yum install -y https://iso.yunion.cn/3.6/rpms/packages/host/baremetal-pxerom-1.1.0-20072810.x86_64.rpm
|
||||
|
||||
FROM frolvlad/alpine-glibc:glibc-2.28
|
||||
|
||||
MAINTAINER "Yaoqi Wan <wanyaoqi@yunionyun.com>"
|
||||
@@ -16,17 +19,17 @@ RUN mkdir -p /opt/cloud/yunion/baremetal
|
||||
RUN wget -O /opt/cloud/yunion/baremetal/pci.ids http://pci-ids.ucw.cz/v2.2/pci.ids
|
||||
|
||||
# download baremetal-pxerom-*.x86_64.rpm and unpack rpm in current directory
|
||||
COPY ./opt/cloud/yunion/baremetal/bootia32.efi /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/bootx64.efi /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/chain.c32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/initramfs /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/isolinux.bin /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/kernel /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/ldlinux.c32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/ldlinux.e32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/ldlinux.e64 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/libcom32.c32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/libutil.c32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/lpxelinux.0 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/menu.c32 /opt/cloud/yunion/baremetal
|
||||
COPY ./opt/cloud/yunion/baremetal/pxelinux.0 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build /opt/cloud/yunion/baremetal/bootia32.efi /opt/cloud/yunion/baremetal
|
||||
COPY --from=build /opt/cloud/yunion/baremetal/bootx64.efi /opt/cloud/yunion/baremetal
|
||||
COPY --from=build /opt/cloud/yunion/baremetal/chain.c32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/initramfs /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/isolinux.bin /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/kernel /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/ldlinux.c32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/ldlinux.e32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/ldlinux.e64 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/libcom32.c32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/libutil.c32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/lpxelinux.0 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/menu.c32 /opt/cloud/yunion/baremetal
|
||||
COPY --from=build ./opt/cloud/yunion/baremetal/pxelinux.0 /opt/cloud/yunion/baremetal
|
||||
|
||||
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}/
|
||||
@@ -6,4 +6,4 @@ ENV TZ Asia/Shanghai
|
||||
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
|
||||
ADD ./_output/alpine-build/bin/host-deployer /opt/yunion/bin/host-deployer
|
||||
ADD ./_output/centos-build/bin/host-deployer /opt/yunion/bin/host-deployer
|
||||
|
||||
@@ -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 .
|
||||
2
build/docker/multi-arch/Dockerfile.host.dockerignore
Normal file
2
build/docker/multi-arch/Dockerfile.host.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
_output/alpine-build/_cache
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px;">您正在验证邮箱,请在验证码输入框中输入:{{.code}},已完成验证。</td>
|
||||
<td style="padding-bottom: 10px;">您正在验证邮箱,请在验证码输入框中输入:{{.code}},以完成验证。</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
@@ -0,0 +1 @@
|
||||
{{.os_type}} image {{.name}} upload completed
|
||||
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table style="width: 650px; margin-bottom: 20px;" border="0" cellpadding="0" cellspacing="0" align="center">
|
||||
<tr style="height: 50px; background: #333; overflow: hidden;">
|
||||
<td>
|
||||
<table style="margin-left: 20px;">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="data:{{.login_logo_format}};base64,{{.login_logo}}" alt="" style="color: #fff; height: 32px; vertical-align: middle;">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td>
|
||||
<table style="float: right;">
|
||||
<tr>
|
||||
<td style="padding-left: 20px; padding-right: 20px;">
|
||||
<a href="" style="text-decoration: none; color: #20A0FF; font-size: 12px; display: none;">Product</a>
|
||||
</td>
|
||||
<td style="padding-left: 20px; padding-right: 20px;">
|
||||
<a href="" style="text-decoration: none; color: #20A0FF; font-size: 12px; display: none;">Solution</a>
|
||||
</td>
|
||||
<td style="padding-left: 20px; padding-right: 20px;">
|
||||
<a href="" style="text-decoration: none; color: #20A0FF; font-size: 12px; display: none;">Service</a>
|
||||
</td>
|
||||
<td style="padding-left: 20px; padding-right: 20px;">
|
||||
<a href="" style="text-decoration: none; color: #20A0FF; font-size: 12px; display: none;">Help and Documentation</a>
|
||||
</td>
|
||||
<td style="padding-left: 20px; padding-right: 20px;">
|
||||
<a href="" style="text-decoration: none; color: #20A0FF; font-size: 12px; display: none;">About</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;" colspan="2">
|
||||
<table style="padding: 20px 10px; width: 100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 13px;">
|
||||
Dear {{.name}}:
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 13px;">You are verifying your email, please enter the following code on the email verification page:</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px; font-size: large">{{.code}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="width: 96%;">
|
||||
<td colspan="2" style="border-top: 1px dashed #ccc; color: #333; font-size: 12px; padding-bottom: 10px; font-weight: 100;">If you are not operating by yourself, please log in to the platform in time and change your password to ensure the security of your account.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="background: #333; text-align: right; padding-right: 20px; font-size: 12px; color: #fff; height: 50px;">Copyrights © {{.copyright}}. All rights reserved.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Image {{.name}} upload completed
|
||||
@@ -0,0 +1 @@
|
||||
{{.copyright}} Verify
|
||||
@@ -452,11 +452,15 @@ func init() {
|
||||
DomainList []string
|
||||
// 是否允许空referer 访问
|
||||
AllowEmptyRefer bool `help:"all empty refer access"`
|
||||
Enabled bool
|
||||
RerererType string `help:"Referer type" choices:"Black-List|White-List"`
|
||||
}
|
||||
R(&BucketSetRefererOption{}, "bucket-set-referer", "Set bucket referer", func(s *mcclient.ClientSession, args *BucketSetRefererOption) error {
|
||||
conf := api.BucketRefererConf{
|
||||
WhiteList: args.DomainList,
|
||||
Enabled: args.Enabled,
|
||||
AllowEmptyRefer: args.AllowEmptyRefer,
|
||||
RefererType: args.RerererType,
|
||||
DomainList: args.DomainList,
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "set-referer", jsonutils.Marshal(conf))
|
||||
if err != nil {
|
||||
|
||||
@@ -42,6 +42,7 @@ func init() {
|
||||
Disabled bool `help:"Show disabled host only" json:"-"`
|
||||
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei|ucloud|google|ctyun"`
|
||||
AnyMac string `help:"Mac matches one of the host's interface"`
|
||||
AnyIp string `help:"IP matches one of the host's interface"`
|
||||
|
||||
IsBaremetal *bool `help:"filter host list by is_baremetal=true|false"`
|
||||
|
||||
|
||||
@@ -15,142 +15,17 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type SecGroupRulesListOptions struct {
|
||||
options.BaseListOptions
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
SecgroupName string `help:"Search rules by fuzzy secgroup name"`
|
||||
Projects []string `help:"Filter rules by project"`
|
||||
Direction string `help:"filter Direction of rule" choices:"in|out"`
|
||||
Protocol string `help:"filter Protocol of rule" choices:"any|tcp|udp|icmp"`
|
||||
Action string `help:"filter Actin of rule" choices:"allow|deny"`
|
||||
Ports string `help:"filter Ports of rule"`
|
||||
Ip string `help:"filter cidr of rule"`
|
||||
}
|
||||
|
||||
R(&SecGroupRulesListOptions{}, "secgroup-rule-list", "List all security group", func(s *mcclient.ClientSession, args *SecGroupRulesListOptions) error {
|
||||
params, err := options.ListStructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.SecGroupRules.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.SecGroupRules.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecGroupRuleDetailOptions struct {
|
||||
ID string `help:"ID or Name of security group rule"`
|
||||
}
|
||||
R(&SecGroupRuleDetailOptions{}, "secgroup-rule-show", "Show details of rule", func(s *mcclient.ClientSession, args *SecGroupRuleDetailOptions) error {
|
||||
if rule, e := modules.SecGroupRules.Get(s, args.ID, nil); e != nil {
|
||||
return e
|
||||
} else {
|
||||
printObject(rule)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&SecGroupRuleDetailOptions{}, "secgroup-rule-delete", "Delete a secgroup rule", func(s *mcclient.ClientSession, args *SecGroupRuleDetailOptions) error {
|
||||
if rule, e := modules.SecGroupRules.Delete(s, args.ID, nil); e != nil {
|
||||
return e
|
||||
} else {
|
||||
printObject(rule)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecGroupRulesCreateOptions struct {
|
||||
SECGROUP string `help:"Secgroup ID or Name" metavar:"Secgroup"`
|
||||
Direction string `help:"Direction of rule" choices:"in|out"`
|
||||
Action string `help:"Action of rule" choices:"allow|deny"`
|
||||
Protocol string `help:"Protocol of rule" choices:"tcp|udp|icmp|any"`
|
||||
Ports string `help:"Ports of rule"`
|
||||
Cidr string `help:"Cidr of rule"`
|
||||
Priority int64 `help:"priority of Rule"`
|
||||
Desc string `help:"Description"`
|
||||
}
|
||||
|
||||
R(&SecGroupRulesCreateOptions{}, "secgroup-rule-create", "Create all security group rule", func(s *mcclient.ClientSession, args *SecGroupRulesCreateOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.Desc) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Desc), "description")
|
||||
}
|
||||
if args.Priority > 0 {
|
||||
params.Add(jsonutils.NewInt(args.Priority), "priority")
|
||||
}
|
||||
if len(args.Direction) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Direction), "direction")
|
||||
}
|
||||
if len(args.Action) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Action), "action")
|
||||
}
|
||||
if len(args.Protocol) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Protocol), "protocol")
|
||||
}
|
||||
if len(args.Ports) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ports), "ports")
|
||||
}
|
||||
if len(args.Cidr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Cidr), "cidr")
|
||||
}
|
||||
params.Add(jsonutils.NewString(args.SECGROUP), "secgroup")
|
||||
secgrouprules, err := modules.SecGroupRules.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(secgrouprules)
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecGroupRulesUpdateOptions struct {
|
||||
ID string `help:"ID or name of rule"`
|
||||
Name string `help:"New name of rule"`
|
||||
Priority int64 `help:"priority of Rule"`
|
||||
Protocol string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
|
||||
Ports string `help:"Ports of rule"`
|
||||
Cidr string `help:"Cidr of rule"`
|
||||
Action string `help:"filter Actin of rule" choices:"allow|deny"`
|
||||
Desc string `help:"Description" metavar:"Description"`
|
||||
}
|
||||
|
||||
R(&SecGroupRulesUpdateOptions{}, "secgroup-rule-update", "Update property of a security group rule", func(s *mcclient.ClientSession, args *SecGroupRulesUpdateOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.Name) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Name), "name")
|
||||
}
|
||||
if len(args.Desc) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Desc), "description")
|
||||
}
|
||||
if args.Priority > 0 {
|
||||
params.Add(jsonutils.NewInt(args.Priority), "priority")
|
||||
}
|
||||
if len(args.Protocol) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Protocol), "protocol")
|
||||
}
|
||||
if len(args.Ports) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ports), "ports")
|
||||
}
|
||||
if len(args.Cidr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Cidr), "cidr")
|
||||
}
|
||||
if len(args.Action) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Action), "action")
|
||||
}
|
||||
if rule, e := modules.SecGroupRules.Update(s, args.ID, params); e != nil {
|
||||
return e
|
||||
} else {
|
||||
printObject(rule)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
cmd := shell.NewResourceCmd(&modules.SecGroupRules).WithKeyword("secgroup-rule")
|
||||
cmd.List(&compute.SecGroupRulesListOptions{})
|
||||
cmd.Show(&options.BaseShowOptions{})
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
cmd.Create(&compute.SecGroupRulesCreateOptions{})
|
||||
cmd.Update(&compute.SecGroupRulesUpdateOptions{})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ func init() {
|
||||
type WireListOptions struct {
|
||||
options.BaseListOptions
|
||||
|
||||
Bandwidth *int `help:"List wires by bandwidth"`
|
||||
|
||||
Region string `help:"List wires in region"`
|
||||
Zone string `help:"list wires in zone" json:"-"`
|
||||
Vpc string `help:"List wires in vpc"`
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
func init() {
|
||||
type IdentityProviderListOptions struct {
|
||||
options.BaseListOptions
|
||||
SsoDomain string `help:"Filter SSO IDP by domain" json:"sso_domain"`
|
||||
}
|
||||
R(&IdentityProviderListOptions{}, "idp-list", "List all identity provider", func(s *mcclient.ClientSession, args *IdentityProviderListOptions) error {
|
||||
params, err := options.ListStructToParams(args)
|
||||
|
||||
@@ -115,7 +115,9 @@ func init() {
|
||||
Enabled bool `help:"update policy enabled"`
|
||||
Disabled bool `help:"update policy disabled"`
|
||||
Desc string `help:"Description"`
|
||||
IsSystem *bool `help:"is_system"`
|
||||
IsSystem bool `help:"is_system"`
|
||||
|
||||
IsNotSystem bool `help:"negative is_system"`
|
||||
}
|
||||
updateFunc := func(s *mcclient.ClientSession, args *PolicyPatchOptions) error {
|
||||
policyId, err := modules.Policies.GetId(s, args.ID, nil)
|
||||
@@ -141,14 +143,13 @@ func init() {
|
||||
if len(args.Desc) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Desc), "description")
|
||||
}
|
||||
if args.IsSystem != nil {
|
||||
if *args.IsSystem {
|
||||
params.Add(jsonutils.JSONTrue, "is_system")
|
||||
} else {
|
||||
params.Add(jsonutils.JSONFalse, "is_system")
|
||||
}
|
||||
if args.IsSystem {
|
||||
params.Add(jsonutils.JSONTrue, "is_system")
|
||||
}
|
||||
result, err := modules.Policies.Patch(s, policyId, params)
|
||||
if args.IsNotSystem {
|
||||
params.Add(jsonutils.JSONFalse, "is_system")
|
||||
}
|
||||
result, err := modules.Policies.Update(s, policyId, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -167,6 +167,32 @@ func initKubeCluster() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ClusterEnableComponentCephCSIOpt{}, cmdN("component-enable-ceph-csi"), "Enable cluster ceph csi component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentCephCSIOpt) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "enable-component", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ClusterEnableComponentMonitorOpt{}, cmdN("component-enable-monitor"), "Enable cluster monitor component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentMonitorOpt) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "enable-component", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ClusterEnableComponentFluentBitOpt{}, cmdN("component-enable-fluentbit"), "Enable cluster fluentbit component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentFluentBitOpt) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
|
||||
@@ -36,6 +36,8 @@ func init() {
|
||||
Email string `help:"The Email"`
|
||||
Docs *string `help:"the Docs website address"`
|
||||
License *string `help:"the license generator website address"`
|
||||
BrandCn *string `help:"the brand name in Chinese"`
|
||||
BrandEn *string `help:"the brand name in English"`
|
||||
}
|
||||
|
||||
R(&CopyrightUpdateOptions{}, "copyright-update", "update copyright", func(s *mcclient.ClientSession, args *CopyrightUpdateOptions) error {
|
||||
@@ -52,6 +54,14 @@ func init() {
|
||||
params.Add(jsonutils.NewString(*args.License), "license")
|
||||
}
|
||||
|
||||
if args.BrandCn != nil {
|
||||
params.Add(jsonutils.NewString(*args.BrandCn), "brand_cn")
|
||||
}
|
||||
|
||||
if args.BrandEn != nil {
|
||||
params.Add(jsonutils.NewString(*args.BrandEn), "brand_en")
|
||||
}
|
||||
|
||||
if len(args.Copyright) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Copyright), "copyright")
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func init() {
|
||||
}
|
||||
R(&ConfigGetTypesOptions{}, "notify-config-get-types", "Get all Config types", func(s *mcclient.ClientSession, args *ConfigGetTypesOptions) error {
|
||||
param := jsonutils.Marshal(args)
|
||||
result, err := modules.NotifyConfig.PerformClassAction(s, "get-types", param)
|
||||
result, err := modules.NotifyReceiver.PerformClassAction(s, "get-types", param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -25,4 +25,6 @@ func init() {
|
||||
cmd.List(new(options.SuggestSysAlertListOptions))
|
||||
cmd.Show(new(options.SSuggestAlertShowOptions))
|
||||
cmd.Perform("ignore", new(options.SuggestAlertIgnoreOptions))
|
||||
cmd_ := shell.NewResourceCmd(monitor.SuggestSysAlertCostManager)
|
||||
cmd_.Get("", new(options.SuggestAlertCostOptions))
|
||||
}
|
||||
|
||||
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-20201219153152-2d901261898c
|
||||
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-20201219153152-2d901261898c h1:71nVDQq1oUjvZknEUNfetdiOB1jZMEfmoQlMUaoPIJs=
|
||||
yunion.io/x/sqlchemy v0.0.0-20201219153152-2d901261898c/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=
|
||||
|
||||
4476
locales/locales.go
4476
locales/locales.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,9 @@ func (h *AuthHandlers) GetRegionsResponse(ctx context.Context, w http.ResponseWr
|
||||
}
|
||||
}
|
||||
resp.Add(domains, "domains")
|
||||
resp.Add(jsonutils.JSONTrue, "return_full_domains")
|
||||
} else {
|
||||
resp.Add(jsonutils.JSONFalse, "return_full_domains")
|
||||
}
|
||||
|
||||
filters := jsonutils.NewDict()
|
||||
@@ -309,9 +312,20 @@ func (h *AuthHandlers) doCredentialLogin(ctx context.Context, req *http.Request,
|
||||
if err != nil {
|
||||
switch httperr := err.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
if httperr.Code >= 500 {
|
||||
return nil, err
|
||||
}
|
||||
if httperr.Code == 409 || httperr.Code == 429 {
|
||||
return nil, err
|
||||
}
|
||||
switch httperr.Class {
|
||||
case "UserNotFound", "WrongPassword":
|
||||
return nil, httperrors.NewJsonClientError(httperrors.ErrIncorrectUsernameOrPassword, "incorrect username or password")
|
||||
case "UserLocked":
|
||||
return nil, httperrors.NewJsonClientError(httperrors.ErrUserLocked, "The user has been locked, please contact the administrator")
|
||||
case "UserDisabled":
|
||||
return nil, httperrors.NewJsonClientError(httperrors.ErrUserDisabled, "The user has been disabled, please contact the administrator")
|
||||
}
|
||||
}
|
||||
return nil, httperrors.NewInvalidCredentialError("invalid credential")
|
||||
}
|
||||
@@ -501,34 +515,34 @@ func (h *AuthHandlers) doLogin(ctx context.Context, w http.ResponseWriter, req *
|
||||
if body.Contains("tenantId") { // switch project
|
||||
token, authToken, err = doTenantLogin(ctx, req, body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "doTenantLogin")
|
||||
return err
|
||||
}
|
||||
userInfo, err = fetchUserInfoFromToken(ctx, req, token)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fetchUserInfoFromToken")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// user/password authenticate
|
||||
// SSO authentication
|
||||
token, err = h.doCredentialLogin(ctx, req, body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "doCredentialLogin")
|
||||
return err
|
||||
}
|
||||
userInfo, err = fetchUserInfoFromToken(ctx, req, token)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fetchUserInfoFromToken")
|
||||
return err
|
||||
}
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
isTotpInit, err := isUserTotpCredInitialed(s, token.GetUserId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "isUserTotpCredInitialed")
|
||||
return err
|
||||
}
|
||||
isIdpLogin := body.Contains("idp_driver")
|
||||
authToken = clientman.NewAuthToken(token.GetTokenString(), isUserEnableTotp(userInfo), isTotpInit, isIdpLogin)
|
||||
}
|
||||
|
||||
if !isUserAllowWebconsole(userInfo) {
|
||||
return errors.Wrap(httperrors.ErrForbidden, "user forbidden login from web")
|
||||
return httperrors.NewForbiddenError("user forbidden login from web")
|
||||
}
|
||||
|
||||
saveAuthCookie(w, authToken, token)
|
||||
@@ -986,6 +1000,12 @@ func getUserInfo2(s *mcclient.ClientSession, uid string, pid string, loginIp str
|
||||
data.Add(jsonutils.JSONFalse, "non_default_domain_projects")
|
||||
}
|
||||
|
||||
if options.Options.EnableQuotaCheck {
|
||||
data.Add(jsonutils.JSONTrue, "enable_quota_check")
|
||||
} else {
|
||||
data.Add(jsonutils.JSONFalse, "enable_quota_check")
|
||||
}
|
||||
|
||||
data.Add(jsonutils.NewString(getSsoCallbackUrl()), "sso_callback_url")
|
||||
|
||||
return data, nil
|
||||
@@ -996,7 +1016,7 @@ func (h *AuthHandlers) getPermissionDetails(ctx context.Context, w http.Response
|
||||
|
||||
_, query, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
var name string
|
||||
@@ -1030,7 +1050,7 @@ func (h *AuthHandlers) doCreatePolicies(ctx context.Context, w http.ResponseWrit
|
||||
// }
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
s := auth.GetSession(ctx, t, FetchRegion(req), "")
|
||||
@@ -1114,7 +1134,7 @@ func (h *AuthHandlers) resetUserPassword(ctx context.Context, w http.ResponseWri
|
||||
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1150,7 +1170,7 @@ func (h *AuthHandlers) resetUserPassword(ctx context.Context, w http.ResponseWri
|
||||
return
|
||||
}
|
||||
}
|
||||
httperrors.InputParameterError(ctx, w, "密码错误")
|
||||
httperrors.InputParameterError(ctx, w, "wrong password")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ func validateTotpRecoverySecrets(s *mcclient.ClientSession, uid string, question
|
||||
func initTotpSecrets(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
t, authToken, err := fetchAuthInfo(ctx, req)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail %s", err)
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail: %s", err)
|
||||
return
|
||||
}
|
||||
if authToken.IsTotpInitialized() {
|
||||
@@ -232,14 +232,14 @@ func initTotpSecrets(ctx context.Context, w http.ResponseWriter, req *http.Reque
|
||||
func validatePasscodeHandler(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
t, authToken, err := fetchAuthInfo(ctx, req)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail %s", err)
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -271,14 +271,14 @@ func validatePasscodeHandler(ctx context.Context, w http.ResponseWriter, req *ht
|
||||
func resetTotpSecrets(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
t, _, err := fetchAuthInfo(ctx, req)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail %s", err)
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ func resetTotpSecrets(ctx context.Context, w http.ResponseWriter, req *http.Requ
|
||||
func listTotpRecoveryQuestions(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
t, _, err := fetchAuthInfo(ctx, req)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail %s", err)
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -335,14 +335,14 @@ func listTotpRecoveryQuestions(ctx context.Context, w http.ResponseWriter, req *
|
||||
func resetTotpRecoveryQuestions(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
t, _, err := fetchAuthInfo(ctx, req)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail %s", err)
|
||||
httperrors.InvalidCredentialError(ctx, w, "fetchAuthInfo fail: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, req)
|
||||
if body == nil {
|
||||
httperrors.InvalidInputError(ctx, w, "body is empty")
|
||||
httperrors.InvalidInputError(ctx, w, "request body is empty")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ func (h *AuthHandlers) handleSsoLogin(ctx context.Context, w http.ResponseWriter
|
||||
case "POST":
|
||||
formData, err := appsrv.Fetch(req)
|
||||
if err != nil {
|
||||
httperrors.InputParameterError(ctx, w, "fetch formdata error: %s", err)
|
||||
httperrors.InputParameterError(ctx, w, "fetch form data error: %s", err)
|
||||
}
|
||||
body, err = jsonutils.ParseQueryString(string(formData))
|
||||
if err != nil {
|
||||
|
||||
@@ -42,6 +42,8 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
const contentTypeSpreadsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
|
||||
const (
|
||||
HOST_MAC = "*MAC地址"
|
||||
HOST_NAME = "*名称"
|
||||
@@ -154,8 +156,8 @@ func (mh *MiscHandler) DoBatchHostRegister(ctx context.Context, w http.ResponseW
|
||||
|
||||
fileHeader := hostfiles[0].Header
|
||||
contentType := fileHeader.Get("Content-Type")
|
||||
if contentType != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {
|
||||
e := httperrors.NewInputParameterError("Wrong content type %s, required application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", contentType)
|
||||
if contentType != contentTypeSpreadsheet {
|
||||
e := httperrors.NewInputParameterError("Wrong content type %s, want %s", contentType, contentTypeSpreadsheet)
|
||||
httperrors.JsonClientError(ctx, w, e)
|
||||
return
|
||||
}
|
||||
@@ -199,7 +201,7 @@ func (mh *MiscHandler) DoBatchHostRegister(ctx context.Context, w http.ResponseW
|
||||
}
|
||||
|
||||
if !titlesOk {
|
||||
httperrors.InputParameterError(ctx, w, "template file is invalid.please check.")
|
||||
httperrors.InputParameterError(ctx, w, "template file is invalid. please check.")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -302,8 +304,8 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
|
||||
fileHeader := userfiles[0].Header
|
||||
contentType := fileHeader.Get("Content-Type")
|
||||
if contentType != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {
|
||||
e := httperrors.NewInputParameterError("Wrong content type %s, required application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", contentType)
|
||||
if contentType != contentTypeSpreadsheet {
|
||||
e := httperrors.NewInputParameterError("Wrong content type %s, want %s", contentType, contentTypeSpreadsheet)
|
||||
httperrors.JsonClientError(ctx, w, e)
|
||||
return
|
||||
}
|
||||
@@ -328,7 +330,7 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
// skipped header row
|
||||
rows := xlsx.GetRows("users")
|
||||
if len(rows) <= 1 {
|
||||
e := httperrors.NewInputParameterError("empty file")
|
||||
e := httperrors.NewInputParameterError("empty file content")
|
||||
httperrors.JsonClientError(ctx, w, e)
|
||||
return
|
||||
} else if len(rows) > BATCH_USER_REGISTER_QUANTITY_LIMITATION {
|
||||
@@ -359,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 {
|
||||
@@ -431,7 +439,7 @@ func (mh *MiscHandler) getDownloadsHandler(ctx context.Context, w http.ResponseW
|
||||
params := appctx.AppContextParams(ctx)
|
||||
template, ok := params["<template_id>"]
|
||||
if !ok || len(template) == 0 {
|
||||
httperrors.InvalidInputError(ctx, w, "not found")
|
||||
httperrors.InvalidInputError(ctx, w, "template_id")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -460,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")
|
||||
|
||||
@@ -142,11 +142,11 @@ func fetchIdList(ctx context.Context, query jsonutils.JSONObject, w http.Respons
|
||||
if e == nil && len(idlist) > 0 {
|
||||
queryDict := query.(*jsonutils.JSONDict)
|
||||
queryDict.Remove("id")
|
||||
log.Debugf("Get idlist: %s", idlist)
|
||||
log.Debugf("Get id list: %s", idlist)
|
||||
return jsonutils.JSONArray2StringArray(idlist)
|
||||
} else {
|
||||
log.Debugf("Cannot find idlist in query: %s", query)
|
||||
httperrors.InvalidInputError(ctx, w, "No idlist found")
|
||||
log.Debugf("Cannot find id list in query: %s", query)
|
||||
httperrors.InvalidInputError(ctx, w, "No id list found")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ type CloudroleListInput struct {
|
||||
apis.StatusInfrasResourceBaseListInput
|
||||
|
||||
CloudaccountResourceListInput
|
||||
CloudgroupResourceListInput
|
||||
}
|
||||
|
||||
type CloudroleDetails struct {
|
||||
|
||||
@@ -320,12 +320,16 @@ func (input *BucketCORSRules) Validate() error {
|
||||
}
|
||||
|
||||
type BucketRefererConf struct {
|
||||
// 白名单域名列表
|
||||
WhiteList []string
|
||||
// 黑名单域名列表
|
||||
BlackList []string
|
||||
// Referer Type
|
||||
// enmu: Black-List, White-List
|
||||
RefererType string
|
||||
// 域名列表
|
||||
DomainList []string
|
||||
// 是否允许空referer 访问
|
||||
AllowEmptyRefer bool
|
||||
|
||||
// 是否开启
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
func (input *BucketRefererConf) Validate() error {
|
||||
|
||||
@@ -335,8 +335,25 @@ type CloudaccountPerformPublicInput struct {
|
||||
type CloudaccountPerformPrepareNetsInput struct {
|
||||
CloudaccountCreateInput
|
||||
|
||||
// description: Recommended network subnet mask
|
||||
// example: 24
|
||||
NetworkBits *int8 `json:"network_bits"`
|
||||
// description: The upper limit of host number
|
||||
// example: 254
|
||||
HostNumberUpperLimit *int `json:"host_number_upper_limit"`
|
||||
// description: The lower limit of host number
|
||||
// example: 2
|
||||
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 {
|
||||
@@ -427,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"`
|
||||
}
|
||||
|
||||
@@ -101,6 +101,50 @@ var (
|
||||
CLOUD_PROVIDER_GOOGLE,
|
||||
CLOUD_PROVIDER_CTYUN,
|
||||
}
|
||||
|
||||
CLOUD_PROVIDER_HOST_TYPE_MAP = map[string][]string{
|
||||
CLOUD_PROVIDER_ONECLOUD: []string{
|
||||
HOST_TYPE_KVM,
|
||||
HOST_TYPE_BAREMETAL,
|
||||
HOST_TYPE_HYPERVISOR,
|
||||
},
|
||||
CLOUD_PROVIDER_VMWARE: []string{
|
||||
HOST_TYPE_ESXI,
|
||||
},
|
||||
CLOUD_PROVIDER_ALIYUN: []string{
|
||||
HOST_TYPE_ALIYUN,
|
||||
},
|
||||
CLOUD_PROVIDER_APSARA: []string{
|
||||
HOST_TYPE_APSARA,
|
||||
},
|
||||
CLOUD_PROVIDER_QCLOUD: []string{
|
||||
HOST_TYPE_QCLOUD,
|
||||
},
|
||||
CLOUD_PROVIDER_AZURE: []string{
|
||||
HOST_TYPE_AZURE,
|
||||
},
|
||||
CLOUD_PROVIDER_AWS: []string{
|
||||
HOST_TYPE_AWS,
|
||||
},
|
||||
CLOUD_PROVIDER_HUAWEI: []string{
|
||||
HOST_TYPE_HUAWEI,
|
||||
},
|
||||
CLOUD_PROVIDER_OPENSTACK: []string{
|
||||
HOST_TYPE_OPENSTACK,
|
||||
},
|
||||
CLOUD_PROVIDER_UCLOUD: []string{
|
||||
HOST_TYPE_UCLOUD,
|
||||
},
|
||||
CLOUD_PROVIDER_ZSTACK: []string{
|
||||
HOST_TYPE_ZSTACK,
|
||||
},
|
||||
CLOUD_PROVIDER_GOOGLE: []string{
|
||||
HOST_TYPE_GOOGLE,
|
||||
},
|
||||
CLOUD_PROVIDER_CTYUN: []string{
|
||||
HOST_TYPE_CTYUN,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -114,6 +114,7 @@ const (
|
||||
CITY_SOUTH_CAROLINA = "South Carolina" //南卡罗来纳州
|
||||
CITY_SALT_LAKE_CITY = "Salt Lake City" //盐湖城
|
||||
CITY_LAS_VEGAS = "Las Vegas" //拉斯维加斯
|
||||
CITY_PHOENIX = "Phoenix" //菲尼克斯
|
||||
|
||||
// 英国
|
||||
CITY_LONDON = "London" //伦敦
|
||||
@@ -150,7 +151,8 @@ const (
|
||||
CITY_STOCKHOLM = "Stockholm" //斯德哥尔摩
|
||||
|
||||
// 巴西
|
||||
CITY_SAO_PAULO = "Sao Paulo" //圣保罗
|
||||
CITY_SAO_PAULO = "Sao Paulo" //圣保罗
|
||||
CITY_RIO_DE_JANEIRO = "Rio de Janeiro" // 里约热内卢
|
||||
|
||||
// 智利
|
||||
CITY_SANTIAGO = "Santiago" // 圣地亚哥
|
||||
@@ -175,6 +177,9 @@ const (
|
||||
// 尼日利亚
|
||||
CITY_LAGOS = "Lagos" //拉哥斯
|
||||
|
||||
// 巴林王国 (中东国家)
|
||||
CITY_BAHRAIN = "Bahrain" // 巴林
|
||||
|
||||
// 越南
|
||||
CITY_HO_CHI_MINH = "Ho Chi Minh" //???
|
||||
|
||||
@@ -205,4 +210,5 @@ const (
|
||||
COUNTRY_CODE_NO = "NO" //挪威
|
||||
COUNTRY_CODE_MX = "MX" //墨西哥
|
||||
COUNTRY_CODE_CL = "CL" //智利
|
||||
COUNTRY_CODE_BH = "BH" //巴林
|
||||
)
|
||||
|
||||
@@ -166,11 +166,7 @@ type SDBInstanceChangeConfigInput struct {
|
||||
apis.Meta
|
||||
|
||||
InstanceType string
|
||||
VCpuCount int
|
||||
VmemSizeMb int
|
||||
StorageType string
|
||||
DiskSizeGB int
|
||||
Category string
|
||||
}
|
||||
|
||||
type SDBInstanceRecoveryConfigInput struct {
|
||||
|
||||
@@ -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"`
|
||||
|
||||
// 镜像
|
||||
|
||||
@@ -159,6 +159,12 @@ type ElasticcacheCreateInput struct {
|
||||
// 主可用区名称或Id
|
||||
Zone string `json:"zone"`
|
||||
|
||||
// 备可用区名称或Id列表
|
||||
// 默认副本与主可用区一致
|
||||
// 支持此参数的云厂商: 腾讯云
|
||||
// required: false
|
||||
SlaveZones []string `json:"slave_zones"`
|
||||
|
||||
// Ip子网名称或Id,建议使用Id
|
||||
// required: true
|
||||
Network string `json:"network"`
|
||||
|
||||
@@ -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"`
|
||||
@@ -372,7 +372,10 @@ type GuestMigrateInput struct {
|
||||
}
|
||||
|
||||
type GuestLiveMigrateInput struct {
|
||||
// 指定期望的迁移目标宿主机
|
||||
PreferHost string `json:"prefer_host"`
|
||||
// 是否跳过CPU检查,默认要做CPU检查
|
||||
SkipCpuCheck *bool `json:"skip_cpu_check"`
|
||||
}
|
||||
|
||||
type GuestSetSecgroupInput struct {
|
||||
@@ -457,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
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ type HostListInput struct {
|
||||
ResourceType string `json:"resource_type"`
|
||||
// filter by mac of any network interface
|
||||
AnyMac string `json:"any_mac"`
|
||||
// filter by ip of any network interface
|
||||
AnyIp string `json:"any_ip"`
|
||||
// filter storages not attached to this host
|
||||
StorageNotAttached *bool `json:"storage_not_attached"`
|
||||
// filter by Hypervisor
|
||||
|
||||
@@ -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"`
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ type SchedtagFilterListInput struct {
|
||||
type SchedtagListInput struct {
|
||||
apis.StandaloneResourceListInput
|
||||
apis.ScopedResourceBaseListInput
|
||||
CloudproviderResourceInput
|
||||
|
||||
// fitler by resource_type
|
||||
ResourceType []string `json:"resource_type"`
|
||||
|
||||
@@ -24,14 +24,12 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type SSecgroupRuleCreateInput struct {
|
||||
apis.ResourceBaseCreateInput
|
||||
|
||||
type SSecgroupRuleResource struct {
|
||||
// 优先级, 数字越大优先级越高
|
||||
// minimum: 1
|
||||
// maximum: 100
|
||||
// required: true
|
||||
Priority int `json:"priority"`
|
||||
Priority *int `json:"priority"`
|
||||
|
||||
// 协议
|
||||
// required: true
|
||||
@@ -68,7 +66,7 @@ type SSecgroupRuleCreateInput struct {
|
||||
// required: true
|
||||
Direction string `json:"direction"`
|
||||
|
||||
// ip或cidr地址
|
||||
// ip或cidr地址, 若指定peer_secgroup_id此参数不生效
|
||||
// example: 192.168.222.121
|
||||
CIDR string `json:"cidr"`
|
||||
|
||||
@@ -84,17 +82,36 @@ type SSecgroupRuleCreateInput struct {
|
||||
// example: test to create rule
|
||||
Description string `json:"description"`
|
||||
|
||||
// 仅单独创建安全组规则时需要指定安全组
|
||||
// required: true
|
||||
Secgroup string `json:"secgroup"`
|
||||
|
||||
// swagger:ignore
|
||||
SecgroupId string
|
||||
// 对端安全组Id, 此参数和cidr参数互斥,并且优先级高于cidr, 同事peer_secgroup_id不能和它所在的安全组ID相同
|
||||
// required: false
|
||||
PeerSecgroupId string `json:"peer_secgroup_id"`
|
||||
}
|
||||
|
||||
func (input *SSecgroupRuleCreateInput) Check() error {
|
||||
type SSecgroupRuleCreateInput struct {
|
||||
apis.ResourceBaseCreateInput
|
||||
SSecgroupRuleResource
|
||||
|
||||
// swagger:ignore
|
||||
Secgroup string `json:"secgroup" yunion-deprecated-by:"secgroup_id"`
|
||||
|
||||
// 安全组ID
|
||||
// required: true
|
||||
SecgroupId string `json:"secgroup_id"`
|
||||
}
|
||||
|
||||
type SSecgroupRuleUpdateInput struct {
|
||||
apis.ResourceBaseUpdateInput
|
||||
|
||||
SSecgroupRuleResource
|
||||
}
|
||||
|
||||
func (input *SSecgroupRuleResource) Check() error {
|
||||
priority := 1
|
||||
if input.Priority != nil {
|
||||
priority = *input.Priority
|
||||
}
|
||||
rule := secrules.SecurityRule{
|
||||
Priority: input.Priority,
|
||||
Priority: priority,
|
||||
Direction: secrules.TSecurityRuleDirection(input.Direction),
|
||||
Action: secrules.TSecurityRuleAction(input.Action),
|
||||
Protocol: input.Protocol,
|
||||
|
||||
@@ -22,5 +22,6 @@ type SecgroupRuleDetails struct {
|
||||
SSecurityGroupRule
|
||||
SecurityGroupResourceInfo
|
||||
|
||||
ProjectId string `json:"tenant_id"`
|
||||
ProjectId string `json:"tenant_id"`
|
||||
PeerSecgroup string `json:"peer_secgroup"`
|
||||
}
|
||||
|
||||
@@ -19,12 +19,13 @@ const (
|
||||
SNAPSHOT_MANUAL = "manual"
|
||||
SNAPSHOT_AUTO = "auto"
|
||||
|
||||
SNAPSHOT_CREATING = "creating"
|
||||
SNAPSHOT_ROLLBACKING = "rollbacking"
|
||||
SNAPSHOT_FAILED = "create_failed"
|
||||
SNAPSHOT_READY = "ready"
|
||||
SNAPSHOT_DELETING = "deleting"
|
||||
SNAPSHOT_UNKNOWN = "unknown"
|
||||
SNAPSHOT_CREATING = "creating"
|
||||
SNAPSHOT_ROLLBACKING = "rollbacking"
|
||||
SNAPSHOT_FAILED = "create_failed"
|
||||
SNAPSHOT_READY = "ready"
|
||||
SNAPSHOT_DELETE_FAILED = "delete_failed"
|
||||
SNAPSHOT_DELETING = "deleting"
|
||||
SNAPSHOT_UNKNOWN = "unknown"
|
||||
|
||||
SNAPSHOT_POLICY_CREATING = "creating"
|
||||
|
||||
|
||||
@@ -146,6 +146,25 @@ var (
|
||||
SHARED_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS, STORAGE_RBD}
|
||||
)
|
||||
|
||||
func IsDiskTypeMatch(t1, t2 string) bool {
|
||||
switch t1 {
|
||||
case DISK_TYPE_ROTATE:
|
||||
if t2 == DISK_TYPE_SSD {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
case DISK_TYPE_SSD:
|
||||
if t2 == DISK_TYPE_ROTATE {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
type StorageResourceInput struct {
|
||||
// 存储(ID或Name)
|
||||
StorageId string `json:"storage_id"`
|
||||
|
||||
@@ -33,6 +33,8 @@ const (
|
||||
|
||||
DEFAULT_VPC_ID = "default"
|
||||
NORMAL_VPC_ID = "normal" // 没有关联VPC的安全组,统一使用normal
|
||||
|
||||
CLASSIC_VPC_NAME = "-"
|
||||
)
|
||||
|
||||
type UsableResourceListInput struct {
|
||||
|
||||
@@ -87,4 +87,6 @@ type WireListInput struct {
|
||||
ZonalFilterListBase
|
||||
|
||||
HostResourceInput
|
||||
|
||||
Bandwidth *int `json:"bandwidth"`
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -31,11 +31,12 @@ type SUserExtended struct {
|
||||
Email string
|
||||
Mobile string
|
||||
|
||||
LocalId int
|
||||
LocalName string
|
||||
DomainName string
|
||||
DomainEnabled bool
|
||||
IsLocal bool
|
||||
LocalId int
|
||||
LocalName string
|
||||
LocalFailedAuthCount int
|
||||
DomainName string
|
||||
DomainEnabled bool
|
||||
IsLocal bool
|
||||
// IdpId string
|
||||
// IdpName string
|
||||
}
|
||||
|
||||
@@ -319,3 +319,7 @@ type EnabledStatusInfrasResourceBaseListInput struct {
|
||||
type MultiArchResourceBaseListInput struct {
|
||||
OsArch string `json:"os_arch"`
|
||||
}
|
||||
|
||||
type AutoDeleteResourceBaseListInput struct {
|
||||
AutoDelete *bool
|
||||
}
|
||||
|
||||
@@ -27,4 +27,14 @@ type BaremetalEventListInput struct {
|
||||
Since time.Time `json:"since"`
|
||||
// until
|
||||
Until time.Time `json:"until"`
|
||||
// host_id
|
||||
HostId []string `json:"host_id"`
|
||||
// id
|
||||
Id []int64 `json:"id"`
|
||||
// EventId
|
||||
EventId []string `json:"event_id"`
|
||||
// Type
|
||||
Type []string `json:"type"`
|
||||
// ipmi_ip
|
||||
IpmiIp []string `json:"ipmi_ip"`
|
||||
}
|
||||
|
||||
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",
|
||||
}
|
||||
)
|
||||
@@ -22,7 +22,7 @@ type AlertResourceType string
|
||||
|
||||
const (
|
||||
// AlertResourceTypeNode means onecloud system infrastructure controller or host node
|
||||
AlertResourceTypeNode AlertResourceType = "node"
|
||||
AlertResourceTypeNode AlertResourceType = "host"
|
||||
// AlertResourceTypeCloudaccount means cloudaccount resource
|
||||
AlertResourceTypeCloudaccount AlertResourceType = "cloudaccount"
|
||||
// AlertResourceTypeVM means virtual machine guest resource
|
||||
|
||||
@@ -120,10 +120,11 @@ type CommonAlertDetails struct {
|
||||
}
|
||||
|
||||
type CommonAlertMetricDetails struct {
|
||||
Comparator string `json:"comparator"`
|
||||
Threshold float64 `json:"threshold"`
|
||||
ConditionType string `json:"condition_type"`
|
||||
ThresholdStr string `json:"threshold_str"`
|
||||
Comparator string `json:"comparator"`
|
||||
Threshold float64 `json:"threshold"`
|
||||
WithinRange []float64 `json:"within_range"`
|
||||
ConditionType string `json:"condition_type"`
|
||||
ThresholdStr string `json:"threshold_str"`
|
||||
// metric points'value的运算方式
|
||||
Reduce string `json:"reduce"`
|
||||
DB string `json:"db"`
|
||||
|
||||
@@ -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"
|
||||
@@ -30,8 +32,8 @@ var (
|
||||
MetricUnit = []string{METRIC_UNIT_PERCENT, METRIC_UNIT_BPS, METRIC_UNIT_MBPS, METRIC_UNIT_BYTEPS, "count/s",
|
||||
METRIC_UNIT_COUNT, METRIC_UNIT_MS, METRIC_UNIT_BYTE, METRIC_UNIT_RMB}
|
||||
ResTypeScoreMap = map[string]int{
|
||||
METRIC_RES_TYPE_HOST: 1,
|
||||
METRIC_RES_TYPE_GUEST: 2,
|
||||
METRIC_RES_TYPE_GUEST: 1,
|
||||
METRIC_RES_TYPE_HOST: 2,
|
||||
METRIC_RES_TYPE_OSS: 3,
|
||||
METRIC_RES_TYPE_RDS: 4,
|
||||
METRIC_RES_TYPE_REDIS: 5,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -62,6 +62,9 @@ const (
|
||||
TEMPLATE_TYPE_CONTENT = "content"
|
||||
TEMPLATE_TYPE_REMOTE = "remote"
|
||||
|
||||
TEMPLATE_LANG_EN = "en"
|
||||
TEMPLATE_LANG_CN = "cn"
|
||||
|
||||
CTYPE_ROBOT_YES = "yes"
|
||||
CTYPE_ROBOT_ONLY = "only"
|
||||
)
|
||||
|
||||
@@ -82,6 +82,8 @@ type ScheduleInput struct {
|
||||
CpuMode string `json:"cpu_mode"`
|
||||
OsArch string `json:"os_arch"`
|
||||
|
||||
SkipCpuCheck *bool `json:"skip_cpu_check"`
|
||||
|
||||
// In the migrate and create backup cases
|
||||
// we don't need reallocate network
|
||||
ReuseNetwork bool `json:"reuse_network"`
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ type IPMIProfile struct {
|
||||
|
||||
func DefaultProfile() IPMIProfile {
|
||||
return IPMIProfile{
|
||||
LanChannel: []int{1},
|
||||
LanChannel: []int{1, 2, 8},
|
||||
RootName: "root",
|
||||
RootId: 2,
|
||||
}
|
||||
@@ -84,14 +84,24 @@ func QemuProfile() IPMIProfile {
|
||||
}
|
||||
}
|
||||
|
||||
func H3CProfile() IPMIProfile {
|
||||
return IPMIProfile{
|
||||
LanChannel: []int{8, 1},
|
||||
RootName: "root",
|
||||
RootId: 2,
|
||||
StrongPass: true,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
PROFILES map[string]IPMIProfile = map[string]IPMIProfile{
|
||||
"inspur": InspurProfile(),
|
||||
"lenovo": LenovoProfile(),
|
||||
"hp": HpProfile(),
|
||||
"huawei": HuaweiProfile(),
|
||||
"foxconn": FoxconnProfile(),
|
||||
"qemu": QemuProfile(),
|
||||
types.OEM_NAME_INSPUR: InspurProfile(),
|
||||
types.OEM_NAME_LENOVO: LenovoProfile(),
|
||||
types.OEM_NAME_HP: HpProfile(),
|
||||
types.OEM_NAME_HUAWEI: HuaweiProfile(),
|
||||
types.OEM_NAME_FOXCONN: FoxconnProfile(),
|
||||
types.OEM_NAME_QEMU: QemuProfile(),
|
||||
types.OEM_NAME_H3C: H3CProfile(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
@@ -47,7 +48,7 @@ func NewBaremetalServerStopTask(
|
||||
func (task *SBaremetalServerStopTask) DoStop(ctx context.Context, args interface{}) error {
|
||||
task.SetStage(task.WaitForStop)
|
||||
if err := task.Baremetal.DoPowerShutdown(true); err != nil {
|
||||
return errors.Wrap(err, "Do power shutdown error")
|
||||
log.Errorf("Do power shutdown error: %s", err)
|
||||
}
|
||||
task.startTime = time.Now()
|
||||
ExecuteTask(task, nil)
|
||||
@@ -73,7 +74,7 @@ func (self *SBaremetalServerStopTask) WaitForStop(ctx context.Context, args inte
|
||||
isSoft = false
|
||||
}
|
||||
if err := self.Baremetal.DoPowerShutdown(isSoft); err != nil {
|
||||
return errors.Wrap(err, "DoPowerShutdown")
|
||||
log.Errorf("DoPowerShutdown soft=%v error: %s", isSoft, err)
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
ExecuteTask(self, nil)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -115,6 +115,8 @@ func (dev *MegaRaidPhyDev) parseLine(line string) bool {
|
||||
dev.Status = "jbod"
|
||||
} else if strings.Contains(strings.ToLower(val), "online") {
|
||||
dev.Status = "online"
|
||||
} else if val == "Rebuild" {
|
||||
dev.Status = "rebuild"
|
||||
} else {
|
||||
dev.Status = "offline"
|
||||
}
|
||||
@@ -624,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
|
||||
}
|
||||
@@ -425,9 +425,6 @@ func Query2List(manager IModelManager, ctx context.Context, userCred mcclient.To
|
||||
extraResults[i].Update(jsonDict)
|
||||
jsonDict = extraResults[i]
|
||||
}
|
||||
if len(exportKeys) > 0 {
|
||||
jsonDict = jsonDict.CopyIncludes(exportKeys...)
|
||||
}
|
||||
if len(fieldFilter) > 0 {
|
||||
jsonDict = jsonDict.CopyIncludes(fieldFilter...)
|
||||
}
|
||||
@@ -791,6 +788,9 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
if len(retList) != retCount {
|
||||
totalCnt = len(retList)
|
||||
}
|
||||
if query.Contains("export_keys") {
|
||||
retList = getExportCols(query, retList)
|
||||
}
|
||||
paginate := false
|
||||
if !customizeFilters.IsEmpty() {
|
||||
// query not use Limit and Offset, do manual pagination
|
||||
@@ -822,6 +822,18 @@ func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64
|
||||
return &retResult
|
||||
}
|
||||
|
||||
func getExportCols(query jsonutils.JSONObject, retList []jsonutils.JSONObject) []jsonutils.JSONObject {
|
||||
var exportKeys stringutils2.SSortedStrings
|
||||
exportKeyStr, _ := query.GetString("export_keys")
|
||||
exportKeys = stringutils2.NewSortedStrings(strings.Split(exportKeyStr, ","))
|
||||
for i := range retList {
|
||||
if len(exportKeys) > 0 {
|
||||
retList[i] = retList[i].(*jsonutils.JSONDict).CopyIncludes(exportKeys...)
|
||||
}
|
||||
}
|
||||
return retList
|
||||
}
|
||||
|
||||
func (dispatcher *DBModelDispatcher) List(ctx context.Context, query jsonutils.JSONObject, ctxIds []dispatcher.SResourceContext) (*modulebase.ListResult, error) {
|
||||
userCred := fetchUserCredential(ctx)
|
||||
|
||||
@@ -920,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 {
|
||||
@@ -459,17 +465,17 @@ func (manager *SMetadataManager) SetValue(ctx context.Context, obj IModel, key s
|
||||
}
|
||||
|
||||
func (manager *SMetadataManager) SetValuesWithLog(ctx context.Context, obj IModel, store map[string]interface{}, userCred mcclient.TokenCredential) error {
|
||||
changes, err := manager.SetValues(ctx, obj, store, userCred)
|
||||
changes, err := manager.setValues(ctx, obj, store, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(changes) > 0 {
|
||||
OpsLog.LogEvent(obj, ACT_SET_METADATA, jsonutils.Marshal(changes), userCred)
|
||||
OpsLog.LogEvent(obj.GetIModel(), ACT_SET_METADATA, jsonutils.Marshal(changes), userCred)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SMetadataManager) SetValues(ctx context.Context, obj IModel, store map[string]interface{}, userCred mcclient.TokenCredential) ([]sMetadataChange, error) {
|
||||
func (manager *SMetadataManager) setValues(ctx context.Context, obj IModel, store map[string]interface{}, userCred mcclient.TokenCredential) ([]sMetadataChange, error) {
|
||||
idStr := GetObjectIdstr(obj)
|
||||
|
||||
// no need to lock
|
||||
@@ -546,9 +552,9 @@ func (manager *SMetadataManager) SetValues(ctx context.Context, obj IModel, stor
|
||||
}
|
||||
|
||||
func (manager *SMetadataManager) SetAll(ctx context.Context, obj IModel, store map[string]interface{}, userCred mcclient.TokenCredential, delRange string) error {
|
||||
changes, err := manager.SetValues(ctx, obj, store, userCred)
|
||||
changes, err := manager.setValues(ctx, obj, store, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "setValues")
|
||||
}
|
||||
|
||||
idStr := GetObjectIdstr(obj)
|
||||
@@ -565,9 +571,9 @@ func (manager *SMetadataManager) SetAll(ctx context.Context, obj IModel, store m
|
||||
q := manager.Query().Equals("id", idStr).NotLike("key", `\_\_%`) //避免删除系统内置的metadata, _ 在mysql里面有特殊含义,需要转义
|
||||
switch delRange {
|
||||
case USER_TAG_PREFIX:
|
||||
q = q.Like("key", USER_TAG_PREFIX+"%")
|
||||
q = q.Startswith("key", USER_TAG_PREFIX)
|
||||
case CLOUD_TAG_PREFIX:
|
||||
q = q.Like("key", CLOUD_TAG_PREFIX+"%")
|
||||
q = q.Startswith("key", CLOUD_TAG_PREFIX)
|
||||
}
|
||||
q = q.Filter(sqlchemy.NOT(sqlchemy.In(q.Field("key"), keys)))
|
||||
if err := FetchModelObjects(manager, q, &records); err != nil {
|
||||
@@ -581,7 +587,7 @@ func (manager *SMetadataManager) SetAll(ctx context.Context, obj IModel, store m
|
||||
changes = append(changes, sMetadataChange{Key: rec.Key, OValue: rec.Value})
|
||||
}
|
||||
if len(changes) > 0 {
|
||||
OpsLog.LogEvent(obj, ACT_SET_METADATA, jsonutils.Marshal(changes), userCred)
|
||||
OpsLog.LogEvent(obj.GetIModel(), ACT_SET_METADATA, jsonutils.Marshal(changes), userCred)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -603,7 +609,7 @@ func (manager *SMetadataManager) GetAll(obj IModel, keys []string, keyPrefix str
|
||||
ret := make(map[string]string)
|
||||
for _, rec := range records {
|
||||
if len(rec.Value) > 0 || strings.HasPrefix(rec.Key, USER_TAG_PREFIX) {
|
||||
ret[rec.Key] = rec.Value
|
||||
ret[strings.ToLower(rec.Key)] = rec.Value
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
@@ -126,7 +126,8 @@ func (manager *SOpsLogManager) LogEvent(model IModel, action string, notes inter
|
||||
if !consts.OpsLogEnabled() {
|
||||
return
|
||||
}
|
||||
if len(model.GetId()) == 0 || len(model.GetName()) == 0 {
|
||||
if len(model.GetId()) == 0 {
|
||||
log.Errorf("logevent for an object without ID???")
|
||||
return
|
||||
}
|
||||
if action == ACT_UPDATE {
|
||||
@@ -384,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)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
@@ -45,7 +46,8 @@ type SEtcdClient struct {
|
||||
onKeepaliveFailure func()
|
||||
leaseLiving bool
|
||||
|
||||
watchers map[string]*SEtcdWatcher
|
||||
watchers map[string]*SEtcdWatcher
|
||||
watchersMu *sync.Mutex
|
||||
}
|
||||
|
||||
func defaultOnKeepAliveFailed() {
|
||||
@@ -115,6 +117,7 @@ func NewEtcdClient(opt *SEtcdOptions, onKeepaliveFailure func()) (*SEtcdClient,
|
||||
etcdClient.leaseTtlTimeout = timeoutSeconds
|
||||
|
||||
etcdClient.watchers = make(map[string]*SEtcdWatcher)
|
||||
etcdClient.watchersMu = &sync.Mutex{}
|
||||
|
||||
etcdClient.namespace = opt.EtcdNamspace
|
||||
|
||||
@@ -306,8 +309,10 @@ func (cli *SEtcdClient) Watch(
|
||||
onModify TEtcdModifyEventFunc,
|
||||
onDelete TEtcdDeleteEventFunc,
|
||||
) error {
|
||||
cli.watchersMu.Lock()
|
||||
_, ok := cli.watchers[prefix]
|
||||
if ok {
|
||||
cli.watchersMu.Unlock()
|
||||
return errors.Errorf("watch prefix %s already registered", prefix)
|
||||
}
|
||||
|
||||
@@ -318,6 +323,7 @@ func (cli *SEtcdClient) Watch(
|
||||
watcher: watcher,
|
||||
cancel: cancel,
|
||||
}
|
||||
cli.watchersMu.Unlock()
|
||||
|
||||
prefix = cli.getKey(prefix)
|
||||
|
||||
@@ -346,6 +352,8 @@ func (cli *SEtcdClient) Watch(
|
||||
}
|
||||
|
||||
func (cli *SEtcdClient) Unwatch(prefix string) {
|
||||
cli.watchersMu.Lock()
|
||||
defer cli.watchersMu.Unlock()
|
||||
watcher, ok := cli.watchers[prefix]
|
||||
if ok {
|
||||
log.Debugf("unwatch %s", prefix)
|
||||
|
||||
@@ -47,6 +47,7 @@ var (
|
||||
ActionPendingDelete SAction = "pending_delete"
|
||||
ActionRebuildRoot SAction = "rebuild_root"
|
||||
ActionChangeConfig SAction = "change_config"
|
||||
ActionChangeIpaddr SAction = "change_ipaddr"
|
||||
)
|
||||
|
||||
type SEvent struct {
|
||||
|
||||
@@ -339,7 +339,11 @@ func genMsgViaLang(ctx context.Context, p sNotifyParams) ([]npk.SNotifyMessage,
|
||||
}
|
||||
|
||||
func intelliNotify(ctx context.Context, p sNotifyParams) {
|
||||
log.Infof("recipientId: %v, contacts: %v, event %s priority %s", p.recipientId, p.contacts, p.event, p.priority)
|
||||
log.Infof("recipientId: %v, contactType: %s, contacts: %v, event %s priority %s", p.recipientId, p.channel, p.contacts, p.event, p.priority)
|
||||
// hack
|
||||
if len(p.recipientId) == 0 && len(p.contacts) == 0 {
|
||||
p.contacts = []string{""}
|
||||
}
|
||||
msgs, err := genMsgViaLang(ctx, p)
|
||||
if err != nil {
|
||||
log.Errorf("unable send notification: %v", err)
|
||||
@@ -433,14 +437,9 @@ func notifyWithChannel(ctx context.Context, p sNotifyParams, channels ...npk.TNo
|
||||
p.recipientId = []string{}
|
||||
p.contacts = []string{}
|
||||
p.channel = c
|
||||
if c == npk.NotifyByWebConsole {
|
||||
p.contacts = reps
|
||||
} else {
|
||||
p.recipientId = reps
|
||||
}
|
||||
p.recipientId = reps
|
||||
rawNotify(ctx, p)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func NotifyImportant(recipientId []string, isGroup bool, event string, data jsonutils.JSONObject) {
|
||||
@@ -519,7 +518,7 @@ func notifyRobot(ctx context.Context, robot string, recipientId []string, isGrou
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("robot", jsonutils.NewString(robot))
|
||||
result, err := modules.NotifyConfig.PerformClassAction(s, "get-types", params)
|
||||
result, err := modules.NotifyReceiver.PerformClassAction(s, "get-types", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user