Skip to content

Commit 4620539

Browse files
committed
[Feat] ✨ Add BallastStone Mechanism to Avoid Instance Action Execute Error mayooot#13
1 parent 45a1315 commit 4620539

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

internal/services/replicaset.go

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import (
2929
"github.com/mayooot/gpu-docker-api/utils"
3030
)
3131

32+
const ballastStone = "var/backups/ballaststone"
33+
3234
var lxcfsBind = []string{
3335
"/var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw",
3436
"/var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw",
@@ -236,10 +238,10 @@ func (rs *ReplicaSetService) ExecuteContainer(name string, exec *models.Containe
236238
}
237239

238240
hijackedResp, err := docker.Cli.ContainerExecAttach(ctx, execCreate.ID, container.ExecAttachOptions{})
239-
defer hijackedResp.Close()
240241
if err != nil {
241242
return resp, errors.Wrapf(err, "docker.ContainerExecAttach failed, name: %s, spec: %+v", name, exec)
242243
}
244+
defer hijackedResp.Close()
243245

244246
var buf bytes.Buffer
245247
_, _ = stdcopy.StdCopy(&buf, &buf, hijackedResp.Reader)
@@ -300,6 +302,11 @@ func (rs *ReplicaSetService) PatchContainer(name string, spec *models.PatchReque
300302
return id, newContainerName, errors.WithMessage(err, "runContainer failed")
301303
}
302304

305+
err = rs.containerRemoveBallastStone(ctrVersionName)
306+
if err != nil {
307+
return id, newContainerName, errors.WithMessage(err, "removeContainerBallastStone failed")
308+
}
309+
303310
// copy the old container's merged files to the new container
304311
err = utils.CopyOldMergedToNewContainerMerged(ctrVersionName, newContainerName)
305312
if err != nil {
@@ -791,6 +798,11 @@ func (rs *ReplicaSetService) RestartContainer(name string) (id, newContainerName
791798
return id, newContainerName, errors.WithMessage(err, "services.runContainer failed")
792799
}
793800

801+
err = rs.containerRemoveBallastStone(ctrVersionName)
802+
if err != nil {
803+
return id, newContainerName, errors.WithMessage(err, "removeContainerBallastStone failed")
804+
}
805+
794806
// copy the old container's merged files to the new container
795807
err = utils.CopyOldMergedToNewContainerMerged(ctrVersionName, newContainerName)
796808
if err != nil {
@@ -895,6 +907,14 @@ func (rs *ReplicaSetService) startContainer(ctx context.Context, respId, ctrVers
895907
return errors.Wrapf(err, "docker.ContainerStart failed, id: %s, name: %s", respId, ctrVersionName)
896908
}
897909

910+
go func(name string) {
911+
time.Sleep(5 * time.Second)
912+
err := rs.containerCreateBallastStone(name)
913+
if err != nil {
914+
log.Errorf("services.containerCreateBallastStone failed, name: %s, err: %v", name, err)
915+
}
916+
}(ctrVersionName)
917+
898918
return nil
899919
}
900920

@@ -962,3 +982,38 @@ func (rs *ReplicaSetService) containerMemory(name string) (int64, error) {
962982
}
963983
return resp.HostConfig.Resources.Memory, nil
964984
}
985+
986+
func (rs *ReplicaSetService) containerCreateBallastStone(name string) error {
987+
containerName := strings.Split(name, "-")[0]
988+
989+
cmds := models.ContainerExecute{
990+
Cmd: []string{
991+
"dd",
992+
"if=/dev/zero",
993+
"of=/" + ballastStone,
994+
"bs=1M",
995+
"count=5", // 5MB
996+
},
997+
}
998+
999+
_, err := rs.ExecuteContainer(containerName, &cmds)
1000+
if err != nil {
1001+
return errors.WithMessagef(err, "services.ExecuteContainer failed, container: %s", containerName)
1002+
}
1003+
1004+
return nil
1005+
}
1006+
1007+
func (rs *ReplicaSetService) containerRemoveBallastStone(name string) error {
1008+
mergedLayer, err := utils.GetContainerMergedLayer(name)
1009+
if err != nil {
1010+
return errors.WithMessagef(err, "utils.GetContainerMergedLayer failed, container: %s", name)
1011+
}
1012+
err = os.Remove(mergedLayer + "/" + ballastStone)
1013+
if err != nil {
1014+
if err != os.ErrExist {
1015+
return errors.WithMessagef(err, "remove container ballast stone failed, path: %s", mergedLayer+"/"+ballastStone)
1016+
}
1017+
}
1018+
return nil
1019+
}

internal/services/replicaset_mock.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ func (rs *ReplicaSetService) runContainer(ctx context.Context, name string, info
9898

9999
if !onlyCreate {
100100
// start container
101-
if err = docker.Cli.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
102-
_ = docker.Cli.ContainerRemove(ctx,
103-
resp.ID,
104-
container.RemoveOptions{Force: true})
105-
info.HostConfig.Resources.DeviceRequests = deviceRequest
101+
if err = rs.startContainer(ctx, resp.ID, ctrVersionName); err != nil {
106102
return "", "", etcd.PutKeyValue{}, errors.Wrapf(err, "docker.ContainerStart failed, id: %s, name: %s", resp.ID, ctrVersionName)
107103
}
108104
}

internal/services/replicaset_nomock.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@ func (rs *ReplicaSetService) runContainer(ctx context.Context, name string, info
7979

8080
if !onlyCreate {
8181
// start container
82-
if err = docker.Cli.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
83-
_ = docker.Cli.ContainerRemove(ctx,
84-
resp.ID,
85-
container.RemoveOptions{Force: true})
82+
if err = rs.startContainer(ctx, resp.ID, ctrVersionName); err != nil {
8683
return "", "", etcd.PutKeyValue{}, errors.Wrapf(err, "docker.ContainerStart failed, id: %s, name: %s", resp.ID, ctrVersionName)
8784
}
8885
}

0 commit comments

Comments
 (0)