Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit c44ffae

Browse files
committed
Merge pull request #188 from gao-feng/pause
support Pause container for hyper
2 parents ae3a477 + 01e5327 commit c44ffae

File tree

7 files changed

+244
-0
lines changed

7 files changed

+244
-0
lines changed

client/pause.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package client
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"strings"
7+
8+
"github.com/hyperhq/hyper/engine"
9+
gflag "github.com/jessevdk/go-flags"
10+
)
11+
12+
func (cli *HyperClient) HyperCmdPause(args ...string) error {
13+
var parser = gflag.NewParser(nil, gflag.Default|gflag.IgnoreUnknown)
14+
parser.Usage = "pause Pod\n\nPause the pod"
15+
args, err := parser.ParseArgs(args)
16+
if err != nil {
17+
if !strings.Contains(err.Error(), "Usage") {
18+
return err
19+
} else {
20+
return nil
21+
}
22+
}
23+
if len(args) == 0 {
24+
return fmt.Errorf("Can not accept the 'pause' command without Pod ID!")
25+
}
26+
27+
v := url.Values{}
28+
v.Set("podId", args[0])
29+
30+
body, _, err := readBody(cli.call("POST", "/pod/pause?"+v.Encode(), nil, nil))
31+
if err != nil {
32+
return err
33+
}
34+
35+
out := engine.NewOutput()
36+
if _, err = out.AddEnv(); err != nil {
37+
return err
38+
}
39+
40+
if _, err := out.Write(body); err != nil {
41+
return err
42+
}
43+
out.Close()
44+
return nil
45+
}

client/unpause.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package client
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"strings"
7+
8+
"github.com/hyperhq/hyper/engine"
9+
gflag "github.com/jessevdk/go-flags"
10+
)
11+
12+
func (cli *HyperClient) HyperCmdUnpause(args ...string) error {
13+
var parser = gflag.NewParser(nil, gflag.Default|gflag.IgnoreUnknown)
14+
parser.Usage = "unpause Pod\n\nUnpause the pod"
15+
args, err := parser.ParseArgs(args)
16+
if err != nil {
17+
if !strings.Contains(err.Error(), "Usage") {
18+
return err
19+
} else {
20+
return nil
21+
}
22+
}
23+
if len(args) == 0 {
24+
return fmt.Errorf("Can not accept the 'unpause' command without Pod ID!")
25+
}
26+
27+
v := url.Values{}
28+
v.Set("podId", args[0])
29+
30+
body, _, err := readBody(cli.call("POST", "/pod/unpause?"+v.Encode(), nil, nil))
31+
if err != nil {
32+
return err
33+
}
34+
out := engine.NewOutput()
35+
if _, err = out.AddEnv(); err != nil {
36+
return err
37+
}
38+
39+
if _, err := out.Write(body); err != nil {
40+
return err
41+
}
42+
out.Close()
43+
return nil
44+
}

daemon/commit.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ func (daemon *Daemon) CmdCommit(job *engine.Job) error {
1313
message := job.Args[4]
1414
pause := job.Args[5]
1515

16+
if pause != "no" {
17+
daemon.PauseContainer(containerId)
18+
defer daemon.UnpauseContainer(containerId)
19+
}
20+
1621
cli := daemon.DockerCli
1722
imgId, _, err := cli.SendContainerCommit(containerId, repo, author, change, message, pause)
1823
if err != nil {

daemon/daemon.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
7878
"build": daemon.CmdBuild,
7979
"commit": daemon.CmdCommit,
8080
"rename": daemon.CmdRename,
81+
"pause": daemon.CmdPause,
82+
"unpause": daemon.CmdUnpause,
8183
"push": daemon.CmdPush,
8284
"podCreate": daemon.CmdPodCreate,
8385
"podStart": daemon.CmdPodStart,

daemon/list.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ func showVM(v *hypervisor.Vm) string {
151151
case types.S_VM_IDLE:
152152
status = "idle"
153153
break
154+
case types.S_VM_PAUSED:
155+
status = "pasued"
156+
break
154157
default:
155158
status = ""
156159
break
@@ -176,6 +179,8 @@ func showPod(pod *hypervisor.PodStatus) string {
176179
if pod.Type == "kubernetes" {
177180
status = "failed(kubernetes)"
178181
}
182+
case types.S_POD_PAUSED:
183+
status = "paused"
179184
case types.S_POD_SUCCEEDED:
180185
status = "succeeded"
181186
if pod.Type == "kubernetes" {
@@ -214,6 +219,8 @@ func showContainer(c *hypervisor.Container) string {
214219
status = "failed"
215220
case types.S_POD_SUCCEEDED:
216221
status = "succeeded"
222+
case types.S_POD_PAUSED:
223+
status = "paused"
217224
default:
218225
status = ""
219226
}

daemon/pause.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package daemon
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/golang/glog"
7+
"github.com/hyperhq/hyper/engine"
8+
"github.com/hyperhq/runv/hypervisor/types"
9+
)
10+
11+
func (daemon *Daemon) CmdPause(job *engine.Job) error {
12+
if len(job.Args) == 0 {
13+
return fmt.Errorf("Can not execute 'pause' command without pod id!")
14+
}
15+
16+
podId := job.Args[0]
17+
glog.V(1).Infof("Pause pod %s", podId)
18+
return daemon.PausePod(podId)
19+
}
20+
21+
func (daemon Daemon) PausePod(podId string) error {
22+
daemon.PodList.RLock()
23+
glog.V(2).Infof("lock read of PodList")
24+
pod, ok := daemon.PodList.Get(podId)
25+
if !ok {
26+
glog.V(2).Infof("unlock read of PodList")
27+
daemon.PodList.RUnlock()
28+
return fmt.Errorf("Can not get Pod info with pod ID(%s)", podId)
29+
}
30+
vmId := pod.status.Vm
31+
glog.V(2).Infof("unlock read of PodList")
32+
daemon.PodList.RUnlock()
33+
34+
vm, ok := daemon.VmList[vmId]
35+
if !ok {
36+
return fmt.Errorf("Can not find VM whose Id is %s!", vmId)
37+
}
38+
39+
if err := vm.Pause(true); err != nil {
40+
return err
41+
}
42+
43+
pod.status.SetContainerStatus(types.S_POD_PAUSED)
44+
pod.status.Status = types.S_POD_PAUSED
45+
vm.Status = types.S_VM_PAUSED
46+
47+
return nil
48+
}
49+
50+
func (daemon Daemon) PauseContainer(container string) error {
51+
glog.V(1).Infof("Get container id is %s", container)
52+
podId, err := daemon.GetPodByContainer(container)
53+
if err != nil {
54+
return err
55+
}
56+
57+
return daemon.PausePod(podId)
58+
}
59+
60+
func (daemon *Daemon) CmdUnpause(job *engine.Job) error {
61+
if len(job.Args) == 0 {
62+
return fmt.Errorf("Can not execute 'pause' command without pod id!")
63+
}
64+
65+
podId := job.Args[0]
66+
glog.V(1).Infof("Unpause pod %s", podId)
67+
return daemon.UnpausePod(podId)
68+
}
69+
70+
func (daemon *Daemon) UnpausePod(podId string) error {
71+
daemon.PodList.RLock()
72+
glog.V(2).Infof("lock read of PodList")
73+
pod, ok := daemon.PodList.Get(podId)
74+
if !ok {
75+
glog.V(2).Infof("unlock read of PodList")
76+
daemon.PodList.RUnlock()
77+
return fmt.Errorf("Can not get Pod info with pod ID(%s)", podId)
78+
}
79+
vmId := pod.status.Vm
80+
glog.V(2).Infof("unlock read of PodList")
81+
daemon.PodList.RUnlock()
82+
83+
if pod.status.Status != types.S_POD_PAUSED {
84+
return fmt.Errorf("pod is not paused")
85+
}
86+
87+
vm, ok := daemon.VmList[vmId]
88+
if !ok {
89+
return fmt.Errorf("Can not find VM whose Id is %s!", vmId)
90+
}
91+
92+
if err := vm.Pause(false); err != nil {
93+
return err
94+
}
95+
96+
pod.status.SetContainerStatus(types.S_POD_RUNNING)
97+
pod.status.Status = types.S_POD_RUNNING
98+
vm.Status = types.S_VM_ASSOCIATED
99+
100+
return nil
101+
}
102+
103+
func (daemon *Daemon) UnpauseContainer(container string) error {
104+
glog.V(1).Infof("Get container id is %s", container)
105+
podId, err := daemon.GetPodByContainer(container)
106+
if err != nil {
107+
return err
108+
}
109+
110+
return daemon.UnpausePod(podId)
111+
}

server/server.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,34 @@ func postContainerRename(eng *engine.Engine, version version.Version, w http.Res
594594
return writeJSONEnv(w, http.StatusOK, env)
595595
}
596596

597+
func postPodPause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
598+
if err := parseForm(r); err != nil {
599+
return err
600+
}
601+
602+
job := eng.Job("pause", r.Form.Get("podId"))
603+
if err := job.Run(); err != nil {
604+
return err
605+
}
606+
607+
w.WriteHeader(http.StatusNoContent)
608+
return nil
609+
}
610+
611+
func postPodUnpause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
612+
if err := parseForm(r); err != nil {
613+
return err
614+
}
615+
616+
job := eng.Job("unpause", r.Form.Get("podId"))
617+
if err := job.Run(); err != nil {
618+
return err
619+
}
620+
621+
w.WriteHeader(http.StatusNoContent)
622+
return nil
623+
}
624+
597625
func postPodCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
598626
if err := parseForm(r); err != nil {
599627
return err
@@ -1188,6 +1216,8 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, corsHeaders stri
11881216
"/pod/labels": postPodLabels,
11891217
"/pod/start": postPodStart,
11901218
"/pod/stop": postStop,
1219+
"/pod/pause": postPodPause,
1220+
"/pod/unpause": postPodUnpause,
11911221
"/service/add": postServiceAdd,
11921222
"/service/update": postServiceUpdate,
11931223
"/tty/resize": postTtyResize,

0 commit comments

Comments
 (0)