Skip to content

Commit 1b9dd80

Browse files
plamenmpetrovamohoste
authored andcommitted
Implemented resume and pause call chain.
Signed-off-by: Plamen Petrov <[email protected]>
1 parent 648f267 commit 1b9dd80

File tree

4 files changed

+111
-36
lines changed

4 files changed

+111
-36
lines changed

firecracker-control/local.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,39 @@ func setShimOOMScore(shimPid int) error {
596596

597597
return nil
598598
}
599+
600+
// PauseVM Pauses a VM
601+
func (s *local) PauseVM(ctx context.Context, req *proto.PauseVMRequest) (*empty.Empty, error) {
602+
client, err := s.shimFirecrackerClient(ctx, req.VMID)
603+
if err != nil {
604+
return nil, err
605+
}
606+
607+
defer client.Close()
608+
609+
resp, err := client.PauseVM(ctx, req)
610+
if err != nil {
611+
s.logger.WithError(err).Error()
612+
return nil, err
613+
}
614+
615+
return resp, nil
616+
}
617+
618+
// ResumeVM Resumes a VM
619+
func (s *local) ResumeVM(ctx context.Context, req *proto.ResumeVMRequest) (*empty.Empty, error) {
620+
client, err := s.shimFirecrackerClient(ctx, req.VMID)
621+
if err != nil {
622+
return nil, err
623+
}
624+
625+
defer client.Close()
626+
627+
resp, err := client.ResumeVM(ctx, req)
628+
if err != nil {
629+
s.logger.WithError(err).Error()
630+
return nil, err
631+
}
632+
633+
return resp, nil
634+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ require (
3333
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
3434
github.com/sirupsen/logrus v1.8.1
3535
github.com/stretchr/testify v1.6.1
36+
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c
3637
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852
3738
go.opencensus.io v0.23.0 // indirect
3839
golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
751751
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
752752
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
753753
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
754+
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
754755
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
755756
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
756757
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=

runtime/service.go

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
package main
1515

1616
import (
17+
"bytes"
1718
"context"
1819
"encoding/json"
1920
"fmt"
2021
"math"
2122
"net"
23+
"net/http"
2224
"os"
2325
"runtime/debug"
2426
"strconv"
@@ -64,6 +66,7 @@ import (
6466
drivemount "github.com/firecracker-microvm/firecracker-containerd/proto/service/drivemount/ttrpc"
6567
fccontrolTtrpc "github.com/firecracker-microvm/firecracker-containerd/proto/service/fccontrol/ttrpc"
6668
ioproxy "github.com/firecracker-microvm/firecracker-containerd/proto/service/ioproxy/ttrpc"
69+
"github.com/tv42/httpunix"
6770
)
6871

6972
func init() {
@@ -157,6 +160,9 @@ type service struct {
157160
// fifos have stdio FIFOs containerd passed to the shim. The key is [taskID][execID].
158161
fifos map[string]map[string]cio.Config
159162
fifosMu sync.Mutex
163+
164+
// httpControlClient is to send pause/resume/snapshot commands to the microVM
165+
httpControlClient *http.Client
160166
}
161167

162168
func shimOpts(shimCtx context.Context) (*shim.Opts, error) {
@@ -620,6 +626,8 @@ func (s *service) createVM(requestCtx context.Context, request *proto.CreateVMRe
620626
return err
621627
}
622628

629+
s.createHTTPControlClient()
630+
623631
s.logger.Info("successfully started the VM")
624632
return nil
625633
}
@@ -672,42 +680,6 @@ func (s *service) StopVM(requestCtx context.Context, request *proto.StopVMReques
672680
return &empty.Empty{}, nil
673681
}
674682

675-
// ResumeVM resumes a VM
676-
func (s *service) ResumeVM(ctx context.Context, req *proto.ResumeVMRequest) (*empty.Empty, error) {
677-
defer logPanicAndDie(s.logger)
678-
679-
err := s.waitVMReady()
680-
if err != nil {
681-
s.logger.WithError(err).Error()
682-
return nil, err
683-
}
684-
685-
if err := s.machine.ResumeVM(ctx); err != nil {
686-
s.logger.WithError(err).Error()
687-
return nil, err
688-
}
689-
690-
return &empty.Empty{}, nil
691-
}
692-
693-
// PauseVM pauses a VM
694-
func (s *service) PauseVM(ctx context.Context, req *proto.PauseVMRequest) (*empty.Empty, error) {
695-
defer logPanicAndDie(s.logger)
696-
697-
err := s.waitVMReady()
698-
if err != nil {
699-
s.logger.WithError(err).Error()
700-
return nil, err
701-
}
702-
703-
if err := s.machine.PauseVM(ctx); err != nil {
704-
s.logger.WithError(err).Error()
705-
return nil, err
706-
}
707-
708-
return &empty.Empty{}, nil
709-
}
710-
711683
// GetVMInfo returns metadata for the VM being managed by this shim. If the VM has not been created yet, this
712684
// method will wait for up to a hardcoded timeout for it to exist, returning an error if the timeout is reached.
713685
func (s *service) GetVMInfo(requestCtx context.Context, request *proto.GetVMInfoRequest) (*proto.GetVMInfoResponse, error) {
@@ -1735,3 +1707,68 @@ func (s *service) monitorVMExit() {
17351707
s.logger.WithError(err).Error("failed to clean up the VM")
17361708
}
17371709
}
1710+
1711+
func (s *service) createHTTPControlClient() {
1712+
u := &httpunix.Transport{
1713+
DialTimeout: 100 * time.Millisecond,
1714+
RequestTimeout: 10 * time.Second,
1715+
ResponseHeaderTimeout: 10 * time.Second,
1716+
}
1717+
u.RegisterLocation("firecracker", s.shimDir.FirecrackerSockPath())
1718+
1719+
t := &http.Transport{}
1720+
t.RegisterProtocol(httpunix.Scheme, u)
1721+
1722+
var client = http.Client{
1723+
Transport: t,
1724+
}
1725+
1726+
s.httpControlClient = &client
1727+
}
1728+
1729+
func formResumeReq() (*http.Request, error) {
1730+
var req *http.Request
1731+
1732+
data := map[string]string{
1733+
"state": "Resumed",
1734+
}
1735+
json, err := json.Marshal(data)
1736+
if err != nil {
1737+
logrus.WithError(err).Error("Failed to marshal json data")
1738+
return nil, err
1739+
}
1740+
1741+
req, err = http.NewRequest("PATCH", "http+unix://firecracker/vm", bytes.NewBuffer(json))
1742+
if err != nil {
1743+
logrus.WithError(err).Error("Failed to create new HTTP request in formResumeReq")
1744+
return nil, err
1745+
}
1746+
req.Header.Add("accept", "application/json")
1747+
req.Header.Add("Content-Type", "application/json")
1748+
1749+
return req, nil
1750+
}
1751+
1752+
func formPauseReq() (*http.Request, error) {
1753+
var req *http.Request
1754+
1755+
data := map[string]string{
1756+
"state": "Paused",
1757+
}
1758+
json, err := json.Marshal(data)
1759+
if err != nil {
1760+
logrus.WithError(err).Error("Failed to marshal json data")
1761+
return nil, err
1762+
}
1763+
1764+
req, err = http.NewRequest("PATCH", "http+unix://firecracker/vm", bytes.NewBuffer(json))
1765+
if err != nil {
1766+
logrus.WithError(err).Error("Failed to create new HTTP request in formPauseReq")
1767+
return nil, err
1768+
}
1769+
req.Header.Add("accept", "application/json")
1770+
req.Header.Add("Content-Type", "application/json")
1771+
1772+
return req, nil
1773+
}
1774+

0 commit comments

Comments
 (0)