mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-22 14:53:30 +00:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
294ef0f17f | |||
32c00f0e9e | |||
2533c065bf |
3
Makefile
3
Makefile
@ -62,4 +62,5 @@ test-e2e:
|
|||||||
sleep 3
|
sleep 3
|
||||||
/usr/local/bin/faas-cli list
|
/usr/local/bin/faas-cli list
|
||||||
sleep 3
|
sleep 3
|
||||||
/usr/local/bin/faas-cli logs figlet --follow=false | grep Forking
|
journalctl -t openfaas-fn:figlet --no-pager
|
||||||
|
/usr/local/bin/faas-cli logs figlet --since 15m --follow=false | grep Forking
|
||||||
|
@ -125,14 +125,16 @@ echo logs | faas-cli invoke figlet
|
|||||||
|
|
||||||
Core services as defined in the docker-compose.yaml file are deployed as containers by faasd.
|
Core services as defined in the docker-compose.yaml file are deployed as containers by faasd.
|
||||||
|
|
||||||
|
The namespace is `openfaas` for core services.
|
||||||
|
|
||||||
View the logs for a component by giving its NAME:
|
View the logs for a component by giving its NAME:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
journalctl -t default:NAME
|
journalctl -t openfaas:NAME
|
||||||
|
|
||||||
journalctl -t default:gateway
|
journalctl -t openfaas:gateway
|
||||||
|
|
||||||
journalctl -t default:queue-worker
|
journalctl -t openfaas:queue-worker
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use `-f` to follow the logs, or `--lines` to tail a number of lines, or `--since` to give a timeframe.
|
You can also use `-f` to follow the logs, or `--lines` to tail a number of lines, or `--since` to give a timeframe.
|
||||||
|
@ -3,4 +3,11 @@ package pkg
|
|||||||
const (
|
const (
|
||||||
// FunctionNamespace is the default containerd namespace functions are created
|
// FunctionNamespace is the default containerd namespace functions are created
|
||||||
FunctionNamespace = "openfaas-fn"
|
FunctionNamespace = "openfaas-fn"
|
||||||
|
|
||||||
|
// faasdNamespace is the containerd namespace services are created
|
||||||
|
faasdNamespace = "openfaas"
|
||||||
|
|
||||||
|
faasServicesPullAlways = false
|
||||||
|
|
||||||
|
defaultSnapshotter = "overlayfs"
|
||||||
)
|
)
|
||||||
|
@ -27,31 +27,34 @@ func Remove(ctx context.Context, client *containerd.Client, name string) error {
|
|||||||
container, containerErr := client.LoadContainer(ctx, name)
|
container, containerErr := client.LoadContainer(ctx, name)
|
||||||
|
|
||||||
if containerErr == nil {
|
if containerErr == nil {
|
||||||
found := true
|
taskFound := true
|
||||||
t, err := container.Task(ctx, nil)
|
t, err := container.Task(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsNotFound(err) {
|
if errdefs.IsNotFound(err) {
|
||||||
found = false
|
taskFound = false
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("unable to get task %s: ", err)
|
return fmt.Errorf("unable to get task %s: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if found {
|
if taskFound {
|
||||||
status, _ := t.Status(ctx)
|
status, err := t.Status(ctx)
|
||||||
fmt.Printf("Status of %s is: %s\n", name, status.Status)
|
|
||||||
|
|
||||||
log.Printf("Need to kill %s\n", name)
|
|
||||||
err := killTask(ctx, t)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("Unable to get status for: %s, error: %s", name, err.Error())
|
||||||
|
} else {
|
||||||
|
log.Printf("Status of %s is: %s\n", name, status.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Need to kill task: %s\n", name)
|
||||||
|
if err = killTask(ctx, t); err != nil {
|
||||||
return fmt.Errorf("error killing task %s, %s, %s", container.ID(), name, err)
|
return fmt.Errorf("error killing task %s, %s, %s", container.ID(), name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = container.Delete(ctx, containerd.WithSnapshotCleanup)
|
if err := container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error deleting container %s, %s, %s", container.ID(), name, err)
|
return fmt.Errorf("error deleting container %s, %s, %s", container.ID(), name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
service := client.SnapshotService("")
|
service := client.SnapshotService("")
|
||||||
key := name + "snapshot"
|
key := name + "snapshot"
|
||||||
@ -70,6 +73,7 @@ func killTask(ctx context.Context, task containerd.Task) error {
|
|||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if task != nil {
|
if task != nil {
|
||||||
@ -114,6 +118,7 @@ func getResolver(ctx context.Context, configFile *configfile.ConfigFile) (remote
|
|||||||
}
|
}
|
||||||
return ac.Username, ac.Password, nil
|
return ac.Username, ac.Password, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
authOpts := []docker.AuthorizerOpt{docker.WithAuthCreds(credFunc)}
|
authOpts := []docker.AuthorizerOpt{docker.WithAuthCreds(credFunc)}
|
||||||
authorizer := docker.NewDockerAuthorizer(authOpts...)
|
authorizer := docker.NewDockerAuthorizer(authOpts...)
|
||||||
opts := docker.ResolverOptions{
|
opts := docker.ResolverOptions{
|
||||||
@ -128,7 +133,7 @@ func PrepareImage(ctx context.Context, client *containerd.Client, imageName, sna
|
|||||||
resolver remotes.Resolver
|
resolver remotes.Resolver
|
||||||
)
|
)
|
||||||
|
|
||||||
if _, stErr := os.Stat(filepath.Join(dockerConfigDir, config.ConfigFileName)); stErr == nil {
|
if _, statErr := os.Stat(filepath.Join(dockerConfigDir, config.ConfigFileName)); statErr == nil {
|
||||||
configFile, err := config.Load(dockerConfigDir)
|
configFile, err := config.Load(dockerConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -137,8 +142,8 @@ func PrepareImage(ctx context.Context, client *containerd.Client, imageName, sna
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return empty, err
|
return empty, err
|
||||||
}
|
}
|
||||||
} else if !os.IsNotExist(stErr) {
|
} else if !os.IsNotExist(statErr) {
|
||||||
return empty, stErr
|
return empty, statErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var image containerd.Image
|
var image containerd.Image
|
||||||
@ -150,7 +155,6 @@ func PrepareImage(ctx context.Context, client *containerd.Client, imageName, sna
|
|||||||
|
|
||||||
image = img
|
image = img
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
img, err := client.GetImage(ctx, imageName)
|
img, err := client.GetImage(ctx, imageName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errdefs.IsNotFound(err) {
|
if !errdefs.IsNotFound(err) {
|
||||||
@ -187,9 +191,11 @@ func pullImage(ctx context.Context, client *containerd.Client, resolver remotes.
|
|||||||
rOpts := []containerd.RemoteOpt{
|
rOpts := []containerd.RemoteOpt{
|
||||||
containerd.WithPullUnpack,
|
containerd.WithPullUnpack,
|
||||||
}
|
}
|
||||||
|
|
||||||
if resolver != nil {
|
if resolver != nil {
|
||||||
rOpts = append(rOpts, containerd.WithResolver(resolver))
|
rOpts = append(rOpts, containerd.WithResolver(resolver))
|
||||||
}
|
}
|
||||||
|
|
||||||
img, err := client.Pull(ctx, imageName, rOpts...)
|
img, err := client.Pull(ctx, imageName, rOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return empty, fmt.Errorf("cannot pull: %s", err)
|
return empty, fmt.Errorf("cannot pull: %s", err)
|
||||||
|
@ -26,14 +26,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultSnapshotter = "overlayfs"
|
|
||||||
workingDirectoryPermission = 0644
|
workingDirectoryPermission = 0644
|
||||||
// faasdNamespace is the containerd namespace services are created
|
|
||||||
faasdNamespace = "default"
|
|
||||||
faasServicesPullAlways = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
// Image is the container image registry reference, in an OCI format.
|
||||||
Image string
|
Image string
|
||||||
Env []string
|
Env []string
|
||||||
Name string
|
Name string
|
||||||
@ -42,6 +39,10 @@ type Service struct {
|
|||||||
Args []string
|
Args []string
|
||||||
DependsOn []string
|
DependsOn []string
|
||||||
Ports []ServicePort
|
Ports []ServicePort
|
||||||
|
|
||||||
|
// User in the docker-compose.yaml spec can set as follows:
|
||||||
|
// a user-id, username, userid:groupid or user:group
|
||||||
|
User string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServicePort struct {
|
type ServicePort struct {
|
||||||
@ -161,12 +162,17 @@ func (s *Supervisor) Start(svcs []Service) error {
|
|||||||
Options: []string{"rbind", "ro"},
|
Options: []string{"rbind", "ro"},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if len(svc.User) > 0 {
|
||||||
|
log.Printf("Running %s with user: %q", svc.Name, svc.User)
|
||||||
|
}
|
||||||
|
|
||||||
newContainer, err := s.client.NewContainer(
|
newContainer, err := s.client.NewContainer(
|
||||||
ctx,
|
ctx,
|
||||||
svc.Name,
|
svc.Name,
|
||||||
containerd.WithImage(image),
|
containerd.WithImage(image),
|
||||||
containerd.WithNewSnapshot(svc.Name+"-snapshot", image),
|
containerd.WithNewSnapshot(svc.Name+"-snapshot", image),
|
||||||
containerd.WithNewSpec(oci.WithImageConfig(image),
|
containerd.WithNewSpec(oci.WithImageConfig(image),
|
||||||
|
withUserOrDefault(svc.User),
|
||||||
oci.WithCapabilities(svc.Caps),
|
oci.WithCapabilities(svc.Caps),
|
||||||
oci.WithMounts(mounts),
|
oci.WithMounts(mounts),
|
||||||
withOCIArgs(svc.Args),
|
withOCIArgs(svc.Args),
|
||||||
@ -201,21 +207,21 @@ func (s *Supervisor) Start(svcs []Service) error {
|
|||||||
|
|
||||||
log.Printf("%s has IP: %s\n", newContainer.ID(), ip.String())
|
log.Printf("%s has IP: %s\n", newContainer.ID(), ip.String())
|
||||||
|
|
||||||
hosts, _ := ioutil.ReadFile("hosts")
|
hosts, err := ioutil.ReadFile("hosts")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Unable to read hosts file: %s\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
hosts = []byte(string(hosts) + fmt.Sprintf(`
|
hosts = []byte(string(hosts) + fmt.Sprintf(`
|
||||||
%s %s
|
%s %s
|
||||||
`, ip, svc.Name))
|
`, ip, svc.Name))
|
||||||
writeErr := ioutil.WriteFile("hosts", hosts, workingDirectoryPermission)
|
|
||||||
|
|
||||||
if writeErr != nil {
|
if err := ioutil.WriteFile("hosts", hosts, workingDirectoryPermission); err != nil {
|
||||||
log.Printf("Error writing file %s %s\n", "hosts", writeErr)
|
log.Printf("Error writing file: %s %s\n", "hosts", err)
|
||||||
}
|
}
|
||||||
// os.Chown("hosts", 101, 101)
|
|
||||||
|
|
||||||
_, err = task.Wait(ctx)
|
if _, err := task.Wait(ctx); err != nil {
|
||||||
if err != nil {
|
log.Printf("Task wait error: %s\n", err)
|
||||||
log.Printf("Wait err: %s\n", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +229,7 @@ func (s *Supervisor) Start(svcs []Service) error {
|
|||||||
// log.Println("Exited: ", exitStatusC)
|
// log.Println("Exited: ", exitStatusC)
|
||||||
|
|
||||||
if err = task.Start(ctx); err != nil {
|
if err = task.Start(ctx); err != nil {
|
||||||
log.Printf("Task err: %s\n", err)
|
log.Printf("Task start error: %s\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,6 +259,16 @@ func (s *Supervisor) Remove(svcs []Service) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withUserOrDefault(userstr string) oci.SpecOpts {
|
||||||
|
if len(userstr) > 0 {
|
||||||
|
return oci.WithUser(userstr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func withOCIArgs(args []string) oci.SpecOpts {
|
func withOCIArgs(args []string) oci.SpecOpts {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return oci.WithProcessArgs(args...)
|
return oci.WithProcessArgs(args...)
|
||||||
@ -305,6 +321,7 @@ func ParseCompose(config *compose.Config) ([]Service, error) {
|
|||||||
Env: env,
|
Env: env,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
DependsOn: s.DependsOn,
|
DependsOn: s.DependsOn,
|
||||||
|
User: s.User,
|
||||||
Ports: convertPorts(s.Ports),
|
Ports: convertPorts(s.Ports),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user