Compare commits

...

4 Commits

Author SHA1 Message Date
Jian Qiu
81a336ea41 fix: skip baremetal-agent riscv64 (#24124)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2026-01-24 20:32:28 +08:00
屈轩
0c9d242f34 fix(region): vendor update (#24119) 2026-01-23 17:03:37 +08:00
屈轩
db2932e20c fix(region): cloudpods container sync (#24114) 2026-01-21 15:35:16 +08:00
Jian Qiu
2d4a3da562 fix: update vendor 4.0.2 20260121 (#24110)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2026-01-21 13:57:24 +08:00
15 changed files with 439 additions and 17 deletions

View File

@@ -260,7 +260,7 @@ dep:
@echo "$$depDeprecated"
@$(MAKE) mod
RELEASE_BRANCH:=release/4.0
RELEASE_BRANCH:=release/4.0.2
GOPROXY ?= direct
mod:

2
go.mod
View File

@@ -98,7 +98,7 @@ require (
k8s.io/cri-api v0.28.15
k8s.io/klog/v2 v2.20.0
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260115023540-d2cc546f0409
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260123023400-1ec07acf830a
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91

4
go.sum
View File

@@ -1661,8 +1661,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
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/cloudmux v0.3.10-0-alpha.1.0.20260115023540-d2cc546f0409 h1:T1CZAt2R7lD3+40hkZHZJyxptrUMCfNmLAh9WEBsISU=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260115023540-d2cc546f0409/go.mod h1:aWRX5Phwz3nbHUNnIAm1oVogjguXPYDDgCOy/9Hnnvk=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260123023400-1ec07acf830a h1:Bo7gZ8J14uP1Dhk910Xbi+UOp3p6fdwJl9Cf2mO6NbI=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260123023400-1ec07acf830a/go.mod h1:aWRX5Phwz3nbHUNnIAm1oVogjguXPYDDgCOy/9Hnnvk=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=

View File

@@ -1192,6 +1192,26 @@ func SyncVMPeripherals(
if err != nil && errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
logclient.AddSimpleActionLog(local, logclient.ACT_CLOUD_SYNC, errors.Wrapf(err, "syncVMIsolateDevice"), userCred, false)
}
err = syncVMContainers(ctx, userCred, provider, local, remote)
if err != nil && errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
logclient.AddSimpleActionLog(local, logclient.ACT_CLOUD_SYNC, errors.Wrapf(err, "syncVMContainers"), userCred, false)
}
}
func syncVMContainers(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localVM *SGuest, remoteVM cloudprovider.ICloudVM) error {
if localVM.Hypervisor != api.HYPERVISOR_POD {
return nil
}
containers, err := remoteVM.GetContainers()
if err != nil {
return errors.Wrap(err, "remoteVM.GetContainers")
}
result := localVM.SyncVMContainers(ctx, userCred, containers)
log.Infof("syncVMContainers for VM %s provider %s result: %s", localVM.Name, provider.Name, result.Result())
if result.IsError() {
return result.AllError()
}
return nil
}
func syncVMNics(
@@ -1314,6 +1334,175 @@ func (self *SGuest) SyncVMIsolateDevices(ctx context.Context, userCred mcclient.
return nil
}
func (guest *SGuest) GetContainers() ([]SContainer, error) {
q := GetContainerManager().Query().Equals("guest_id", guest.Id)
ret := []SContainer{}
err := db.FetchModelObjects(GetContainerManager(), q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "GetContainers")
}
return ret, nil
}
func (guest *SGuest) SyncVMContainers(
ctx context.Context,
userCred mcclient.TokenCredential,
containers []cloudprovider.ICloudContainer,
) compare.SyncResult {
lockman.LockRawObject(ctx, guest.Id, GetContainerManager().Keyword())
defer lockman.ReleaseRawObject(ctx, guest.Id, GetContainerManager().Keyword())
result := compare.SyncResult{}
dbContainers, err := guest.GetContainers()
if err != nil {
result.Error(errors.Wrapf(err, "GetContainers"))
return result
}
removed := make([]SContainer, 0)
commondb := make([]SContainer, 0)
commonext := make([]cloudprovider.ICloudContainer, 0)
added := make([]cloudprovider.ICloudContainer, 0)
err = compare.CompareSets(dbContainers, containers, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrapf(err, "compare.CompareSets"))
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].Delete(ctx, userCred)
if err != nil {
result.AddError(errors.Wrapf(err, "Delete(%s)", removed[i].Id))
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
if commondb[i].PendingDeleted != guest.PendingDeleted { //避免主机正常,磁盘在回收站的情况
db.Update(&commondb[i], func() error {
commondb[i].PendingDeleted = guest.PendingDeleted
return nil
})
}
err := commondb[i].SyncWithCloudContainer(ctx, userCred, commonext[i])
if err != nil {
result.AddError(errors.Wrapf(err, "SyncWithCloudContainer(%s)", commondb[i].Id))
continue
}
commondb[i].SyncCloudProjectId(userCred, guest.GetOwnerId())
result.Update()
}
for i := 0; i < len(added); i += 1 {
err := guest.syncNewContainer(ctx, userCred, added[i])
if err != nil {
result.AddError(errors.Wrapf(err, "syncNewContainer(%s)", added[i].GetGlobalId()))
continue
}
result.Add()
}
return result
}
func (self *SContainer) SyncWithCloudContainer(ctx context.Context, userCred mcclient.TokenCredential, container cloudprovider.ICloudContainer) error {
_, err := db.Update(self, func() error {
self.Status = container.GetStatus()
self.Spec.Image = container.GetImage()
self.Spec.Command = container.GetCommand()
self.Spec.Envs = make([]*apis.ContainerKeyValue, 0)
for _, env := range container.GetEnvs() {
self.Spec.Envs = append(self.Spec.Envs, &apis.ContainerKeyValue{
Key: env.Key,
Value: env.Value,
})
}
self.Spec.VolumeMounts = make([]*apis.ContainerVolumeMount, 0)
volumeMounts, err := container.GetVolumentMounts()
if err != nil && err != cloudprovider.ErrNotImplemented {
return errors.Wrapf(err, "GetVolumentMounts")
}
for _, volumeMount := range volumeMounts {
self.Spec.VolumeMounts = append(self.Spec.VolumeMounts, &apis.ContainerVolumeMount{
UniqueName: volumeMount.GetName(),
ReadOnly: volumeMount.IsReadOnly(),
Type: apis.ContainerVolumeMountType(volumeMount.GetType()),
})
}
self.Spec.Devices = make([]*api.ContainerDevice, 0)
devices, err := container.GetDevices()
if err != nil && err != cloudprovider.ErrNotImplemented {
return errors.Wrapf(err, "GetDevices")
}
for _, device := range devices {
self.Spec.Devices = append(self.Spec.Devices, &api.ContainerDevice{
IsolatedDevice: &api.ContainerIsolatedDevice{
Id: device.GetId(),
},
Type: apis.ContainerDeviceType(device.GetType()),
})
}
return nil
})
return err
}
func (guest *SGuest) syncNewContainer(ctx context.Context, userCred mcclient.TokenCredential, container cloudprovider.ICloudContainer) error {
res := &SContainer{
GuestId: guest.Id,
Spec: &api.ContainerSpec{},
}
res.SetModelManager(GetContainerManager(), res)
res.DomainId = guest.DomainId
res.ProjectId = guest.ProjectId
res.StartedAt = container.GetStartedAt()
res.LastFinishedAt = container.GetLastFinishedAt()
res.RestartCount = container.GetRestartCount()
res.ExternalId = container.GetGlobalId()
res.Name = container.GetName()
res.Status = container.GetStatus()
res.Spec.Image = container.GetImage()
res.Spec.Command = container.GetCommand()
res.Spec.Envs = make([]*apis.ContainerKeyValue, 0)
for _, env := range container.GetEnvs() {
res.Spec.Envs = append(res.Spec.Envs, &apis.ContainerKeyValue{
Key: env.Key,
Value: env.Value,
})
}
res.Spec.VolumeMounts = make([]*apis.ContainerVolumeMount, 0)
volumeMounts, err := container.GetVolumentMounts()
if err != nil && err != cloudprovider.ErrNotImplemented {
log.Errorf("GetVolumentMounts error: %v", err)
}
for _, volumeMount := range volumeMounts {
res.Spec.VolumeMounts = append(res.Spec.VolumeMounts, &apis.ContainerVolumeMount{
UniqueName: volumeMount.GetName(),
ReadOnly: volumeMount.IsReadOnly(),
Type: apis.ContainerVolumeMountType(volumeMount.GetType()),
})
}
res.Spec.Devices = make([]*api.ContainerDevice, 0)
devices, err := container.GetDevices()
if err != nil && err != cloudprovider.ErrNotImplemented {
log.Errorf("GetDevices error: %v", err)
}
for _, device := range devices {
res.Spec.Devices = append(res.Spec.Devices, &api.ContainerDevice{
IsolatedDevice: &api.ContainerIsolatedDevice{
Id: device.GetId(),
},
Type: apis.ContainerDeviceType(device.GetType()),
})
}
err = GetContainerManager().TableSpec().Insert(ctx, res)
if err != nil {
return errors.Wrapf(err, "Insert(%s)", res.Id)
}
return nil
}
func syncSkusFromPrivateCloud(
ctx context.Context,
userCred mcclient.TokenCredential,

View File

@@ -72,6 +72,7 @@ type SContainerManager struct {
type SContainer struct {
db.SVirtualResourceBase
db.SExternalizedResourceBase
// GuestId is also the pod id
GuestId string `width:"36" charset:"ascii" create:"required" list:"user" index:"true"`

View File

@@ -574,6 +574,7 @@ func fetchGuestNICs(ctx context.Context, guestIds []string, virtual tristate.Tri
gnwq.Field("network_id"), // caution: do not alias netq.id as network_id
gnwq.Field("port_mappings"),
gnwq.Field("ifname"),
gnwq.Field("is_default"),

View File

@@ -0,0 +1,159 @@
// 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 cloudpods
import (
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
type SContainer struct {
multicloud.SResourceBase
CloudpodsTags
region *SRegion
api.SContainer
}
func (region *SRegion) GetContainers(guestId string) ([]SContainer, error) {
ret := []SContainer{}
params := map[string]interface{}{
"guest_id": guestId,
}
err := region.list(&modules.Containers, params, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (container *SContainer) GetId() string {
return container.Id
}
func (container *SContainer) GetGlobalId() string {
return container.Id
}
func (container *SContainer) GetName() string {
return container.Name
}
func (container *SContainer) GetStatus() string {
return container.Status
}
func (container *SContainer) GetStartedAt() time.Time {
return container.StartedAt
}
func (container *SContainer) GetLastFinishedAt() time.Time {
return container.LastFinishedAt
}
func (container *SContainer) GetRestartCount() int {
return container.RestartCount
}
func (container *SContainer) GetVolumentMounts() ([]cloudprovider.ICloudVolumeMount, error) {
if container.Spec == nil {
return []cloudprovider.ICloudVolumeMount{}, nil
}
ret := []cloudprovider.ICloudVolumeMount{}
for id := range container.Spec.VolumeMounts {
ret = append(ret, &SContainerVolumeMount{
container.Spec.VolumeMounts[id],
})
}
return ret, nil
}
func (container *SContainer) GetDevices() ([]cloudprovider.IContainerDevice, error) {
if container.Spec == nil {
return []cloudprovider.IContainerDevice{}, nil
}
ret := []cloudprovider.IContainerDevice{}
for id := range container.Spec.Devices {
ret = append(ret, &SContainerDevice{
container.Spec.Devices[id],
})
}
return ret, nil
}
type SContainerVolumeMount struct {
*apis.ContainerVolumeMount
}
func (volumeMount *SContainerVolumeMount) GetName() string {
return volumeMount.UniqueName
}
func (volumeMount *SContainerVolumeMount) IsReadOnly() bool {
return volumeMount.ReadOnly
}
func (volumeMount *SContainerVolumeMount) GetType() string {
return string(volumeMount.Type)
}
type SContainerDevice struct {
*api.ContainerDevice
}
func (device *SContainerDevice) GetId() string {
if device.IsolatedDevice != nil {
return device.IsolatedDevice.Id
}
return ""
}
func (device *SContainerDevice) GetType() string {
return string(device.Type)
}
func (container *SContainer) GetImage() string {
if container.Spec == nil {
return ""
}
return container.Spec.Image
}
func (container *SContainer) GetCommand() []string {
if container.Spec == nil {
return []string{}
}
return container.Spec.Command
}
func (container *SContainer) GetEnvs() []cloudprovider.SContainerEnv {
if container.Spec == nil {
return []cloudprovider.SContainerEnv{}
}
envs := make([]cloudprovider.SContainerEnv, 0)
for _, env := range container.Spec.Envs {
envs = append(envs, cloudprovider.SContainerEnv{
Key: env.Key,
Value: env.Value,
})
}
return envs
}

View File

@@ -614,3 +614,16 @@ func (vm *SInstance) GetIsolateDeviceIds() ([]string, error) {
}
return ret, nil
}
func (vm *SInstance) GetContainers() ([]cloudprovider.ICloudContainer, error) {
containers, err := vm.host.zone.region.GetContainers(vm.Id)
if err != nil {
return nil, err
}
ret := []cloudprovider.ICloudContainer{}
for i := range containers {
containers[i].region = vm.host.zone.region
ret = append(ret, &containers[i])
}
return ret, nil
}

View File

@@ -214,6 +214,18 @@ general_build() {
fi
}
make_manifest_image2() {
local component=$1
local img_name=$(get_image_name $component "" "false")
if [[ "$DRY_RUN" == "true" ]]; then
echo "[$(readlink -f ${BASH_SOURCE}):${LINENO} ${FUNCNAME[0]}] return for DRY_RUN"
return
fi
docker buildx imagetools create -t $img_name \
$img_name-amd64 \
$img_name-arm64
}
make_manifest_image() {
local component=$1
local img_name=$(get_image_name $component "" "false")
@@ -314,16 +326,21 @@ for component in $COMPONENTS; do
case "$ARCH" in
all)
for arch in "arm64" "amd64" "riscv64"; do
general_build $component $arch "true"
done
make_manifest_image $component
#show_update_cmd $component $ARCH
if [[ $component == "baremetal-agent" ]]; then
for arch in "arm64" "amd64"; do
general_build $component $arch "true"
done
make_manifest_image2 $component
else
for arch in "arm64" "amd64" "riscv64"; do
general_build $component $arch "true"
done
make_manifest_image $component
fi
;;
*)
if [ -e "$DOCKER_DIR/Dockerfile.$component" ]; then
general_build $component $ARCH "false"
#show_update_cmd $component $ARCH
fi
;;
esac

2
vendor/modules.txt vendored
View File

@@ -2243,7 +2243,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260115023540-d2cc546f0409
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260123023400-1ec07acf830a
## explicit; go 1.24
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing

View File

@@ -367,11 +367,6 @@ type ICloudVM interface {
GetVga() string
GetVdi() string
// GetOSArch() string
// GetOsType() TOsType
// GetOSName() string
// GetBios() string
GetMachine() string
GetInstanceType() string
@@ -418,6 +413,39 @@ type ICloudVM interface {
GetPowerStates() string
GetHealthStatus() string
GetIsolateDeviceIds() ([]string, error)
GetContainers() ([]ICloudContainer, error)
}
type SContainerEnv struct {
Key string
Value string
}
type ICloudContainer interface {
ICloudResource
GetImage() string
GetCommand() []string
GetEnvs() []SContainerEnv
GetStartedAt() time.Time
GetLastFinishedAt() time.Time
GetRestartCount() int
GetVolumentMounts() ([]ICloudVolumeMount, error)
GetDevices() ([]IContainerDevice, error)
}
type ICloudVolumeMount interface {
GetName() string
IsReadOnly() bool
GetType() string
}
type IContainerDevice interface {
GetId() string
GetType() string
}
type ICloudNic interface {

View File

@@ -102,3 +102,7 @@ func (instance *SInstanceBase) GetError() error {
func (instance *SInstanceBase) GetIsolateDeviceIds() ([]string, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIsolateDeviceIds")
}
func (instance *SInstanceBase) GetContainers() ([]cloudprovider.ICloudContainer, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetContainers")
}

View File

@@ -292,3 +292,7 @@ func (self *SInstance) GetHealthStatus() string {
func (self *SInstance) GetIsolateDeviceIds() ([]string, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SInstance) GetContainers() ([]cloudprovider.ICloudContainer, error) {
return nil, cloudprovider.ErrNotSupported
}

View File

@@ -36,6 +36,7 @@ var RegionLocations = map[string]string{
"cn-shanghai": "华东2上海",
"cn-guangzhou": "华南1广州",
"ap-southeast-1": "亚太东南(柔佛)",
"ap-southeast-3": "亚太东南(雅加达)",
"cn-hongkong": "中国香港",
}
@@ -45,6 +46,7 @@ var RegionEndpoint = map[string]string{
"cn-guangzhou": "cn-beijing.volces.com",
"ap-southeast-1": "ap-southeast-1.volces.com",
"cn-hongkong": "cn-hongkong.volces.com",
"ap-southeast-3": "ap-southeast-3.volces.com",
}
type sStorageType struct {
@@ -509,7 +511,11 @@ func (region *SRegion) instanceOperation(instanceId string, apiName string, extr
}
func (region *SRegion) getBaseEndpoint() string {
return RegionEndpoint[region.RegionId]
endpoint, ok := RegionEndpoint[region.RegionId]
if ok {
return endpoint
}
return fmt.Sprintf("%s.volces.com", region.RegionId)
}
func (region *SRegion) getS3Endpoint() string {