split container slot reconciliation
This commit is contained in:
@@ -191,5 +191,6 @@
|
|||||||
|
|
||||||
- daemon server 将请求读取、进度回调、更新/重启分派、诊断分派拆开,保留协议错误文本与响应行为。
|
- daemon server 将请求读取、进度回调、更新/重启分派、诊断分派拆开,保留协议错误文本与响应行为。
|
||||||
- `runServe` 将 native/container 运行时构建与资源关闭拆出,避免入口函数承担全部分支。
|
- `runServe` 将 native/container 运行时构建与资源关闭拆出,避免入口函数承担全部分支。
|
||||||
|
- 容器槽位现场核对拆为容器检查、已提交部署校验和活动槽位选择,减少单函数分支嵌套。
|
||||||
|
|
||||||
验证:`GOCACHE=/tmp/yms-go-cache go test ./...`、`git diff --check` 通过。
|
验证:`GOCACHE=/tmp/yms-go-cache go test ./...`、`git diff --check` 通过。
|
||||||
|
|||||||
@@ -337,40 +337,19 @@ func (u *Updater) resolveContainerSlots(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", err
|
return 0, deploymentconfig.BackendSlot{}, "", err
|
||||||
}
|
}
|
||||||
active, activeErr := u.engine.InspectContainer(ctx, activeSlot.ContainerName)
|
active, activeFound, err := u.inspectSlotContainer(ctx, activeSlot.ContainerName, "active")
|
||||||
if activeErr != nil && !errors.Is(activeErr, containerengine.ErrNotFound) {
|
if err != nil {
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inspect active backend container %s: %w", activeSlot.ContainerName, activeErr)
|
return 0, deploymentconfig.BackendSlot{}, "", err
|
||||||
}
|
}
|
||||||
inactive, inactiveErr := u.engine.InspectContainer(ctx, inactiveSlot.ContainerName)
|
inactive, inactiveFound, err := u.inspectSlotContainer(ctx, inactiveSlot.ContainerName, "inactive")
|
||||||
if inactiveErr != nil && !errors.Is(inactiveErr, containerengine.ErrNotFound) {
|
if err != nil {
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inspect inactive backend container %s: %w", inactiveSlot.ContainerName, inactiveErr)
|
return 0, deploymentconfig.BackendSlot{}, "", err
|
||||||
}
|
}
|
||||||
activeFound := activeErr == nil
|
if err := validateCommittedContainer(deployment, activePort, activeSlot, active, activeFound, hasDeployment); err != nil {
|
||||||
inactiveFound := inactiveErr == nil
|
return 0, deploymentconfig.BackendSlot{}, "", err
|
||||||
|
|
||||||
if hasDeployment {
|
|
||||||
if deployment.ActivePort != activePort {
|
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed backend container port %d does not match gateway active port %d", deployment.ActivePort, activePort)
|
|
||||||
}
|
}
|
||||||
if deployment.ContainerName != activeSlot.ContainerName {
|
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed backend container %s does not match gateway slot container %s", deployment.ContainerName, activeSlot.ContainerName)
|
|
||||||
}
|
|
||||||
if !activeFound {
|
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed active backend container %s is missing", activeSlot.ContainerName)
|
|
||||||
}
|
|
||||||
if active.ID != deployment.ContainerID {
|
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s identity does not match committed deployment", activeSlot.ContainerName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if activeFound {
|
if activeFound {
|
||||||
if !active.Running || active.Dead {
|
return selectRunningContainerSlot(inactivePort, activeSlot, inactiveSlot, active, inactive, inactiveFound)
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is not running", activeSlot.ContainerName)
|
|
||||||
}
|
|
||||||
if inactiveFound && inactive.Running && !inactive.Dead {
|
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inactive backend container %s is unexpectedly running", inactiveSlot.ContainerName)
|
|
||||||
}
|
|
||||||
return inactivePort, inactiveSlot, activeSlot.ContainerName, nil
|
|
||||||
}
|
}
|
||||||
if hasHistory {
|
if hasHistory {
|
||||||
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is missing on a server with committed backend container transaction history", activeSlot.ContainerName)
|
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is missing on a server with committed backend container transaction history", activeSlot.ContainerName)
|
||||||
@@ -381,6 +360,46 @@ func (u *Updater) resolveContainerSlots(
|
|||||||
return inactivePort, inactiveSlot, "", nil
|
return inactivePort, inactiveSlot, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *Updater) inspectSlotContainer(ctx context.Context, name string, role string) (containerengine.Container, bool, error) {
|
||||||
|
container, err := u.engine.InspectContainer(ctx, name)
|
||||||
|
if errors.Is(err, containerengine.ErrNotFound) {
|
||||||
|
return containerengine.Container{}, false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return containerengine.Container{}, false, fmt.Errorf("inspect %s backend container %s: %w", role, name, err)
|
||||||
|
}
|
||||||
|
return container, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCommittedContainer(deployment transaction.BackendContainerDeployment, activePort int, activeSlot deploymentconfig.BackendSlot, active containerengine.Container, found bool, hasDeployment bool) error {
|
||||||
|
if !hasDeployment {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if deployment.ActivePort != activePort {
|
||||||
|
return fmt.Errorf("committed backend container port %d does not match gateway active port %d", deployment.ActivePort, activePort)
|
||||||
|
}
|
||||||
|
if deployment.ContainerName != activeSlot.ContainerName {
|
||||||
|
return fmt.Errorf("committed backend container %s does not match gateway slot container %s", deployment.ContainerName, activeSlot.ContainerName)
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return fmt.Errorf("committed active backend container %s is missing", activeSlot.ContainerName)
|
||||||
|
}
|
||||||
|
if active.ID != deployment.ContainerID {
|
||||||
|
return fmt.Errorf("active backend container %s identity does not match committed deployment", activeSlot.ContainerName)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func selectRunningContainerSlot(inactivePort int, activeSlot, inactiveSlot deploymentconfig.BackendSlot, active, inactive containerengine.Container, inactiveFound bool) (int, deploymentconfig.BackendSlot, string, error) {
|
||||||
|
if !active.Running || active.Dead {
|
||||||
|
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is not running", activeSlot.ContainerName)
|
||||||
|
}
|
||||||
|
if inactiveFound && inactive.Running && !inactive.Dead {
|
||||||
|
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inactive backend container %s is unexpectedly running", inactiveSlot.ContainerName)
|
||||||
|
}
|
||||||
|
return inactivePort, inactiveSlot, activeSlot.ContainerName, nil
|
||||||
|
}
|
||||||
|
|
||||||
// resolvedImage 拉取并解析后得到的镜像信息。
|
// resolvedImage 拉取并解析后得到的镜像信息。
|
||||||
type resolvedImage struct {
|
type resolvedImage struct {
|
||||||
// ImmutableReference 带摘要的不可变镜像引用。
|
// ImmutableReference 带摘要的不可变镜像引用。
|
||||||
|
|||||||
Reference in New Issue
Block a user