Fix unhandled range error and extend deletion timeout

Fixes a bug when attempting to access a non-existant IP from
GetIPfromPID called via the list API.

Renames the provider from faas-containerd

Updates function deletion grace period to 30s to prevent any
errors in the REST API during a long-running deletion.

Tested on Linux with the figlet function which by default takes
around 5s to delete due to its write_timeout value, the deletion
now blocks rather than throwing an error.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
This commit is contained in:
Alex Ellis (OpenFaaS Ltd) 2020-01-26 21:03:37 +00:00
parent a4710db664
commit 969fc566e1
5 changed files with 23 additions and 7 deletions

View File

@ -161,8 +161,12 @@ func GetIPfromPID(pid int) (*net.IP, error) {
if addrsErr != nil { if addrsErr != nil {
return nil, fmt.Errorf("unable to find address for veth pair using: %v %s", peerIDs, addrsErr) return nil, fmt.Errorf("unable to find address for veth pair using: %v %s", peerIDs, addrsErr)
} }
return &addrs[0].CIDRs[0].IP, nil
if len(addrs) > 0 && len(addrs[0].CIDRs) > 0 {
return &addrs[0].CIDRs[0].IP, nil
}
return nil, fmt.Errorf("no IP found for function")
} }
// NetID generates the network IF based on task name and task PID // NetID generates the network IF based on task name and task PID

View File

@ -60,8 +60,13 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
if svc.Status == "running" { if svc.Status == "running" {
replicas = 1 replicas = 1
f.pid = task.Pid() f.pid = task.Pid()
// Get container IP address // Get container IP address
ip, _ := GetIPfromPID(int(task.Pid())) ip, getIPErr := GetIPfromPID(int(task.Pid()))
if getIPErr != nil {
return Function{}, getIPErr
}
f.IP = ip.String() f.IP = ip.String()
} }
} else { } else {

View File

@ -49,6 +49,8 @@ func MakeDeleteHandler(client *containerd.Client, cni gocni.CNI) func(w http.Res
} }
ctx := namespaces.WithNamespace(context.Background(), FunctionNamespace) ctx := namespaces.WithNamespace(context.Background(), FunctionNamespace)
// TODO: this needs to still happen if the task is paused
if function.replicas != 0 { if function.replicas != 0 {
err = DeleteCNINetwork(ctx, cni, client, name) err = DeleteCNINetwork(ctx, cni, client, name)
if err != nil { if err != nil {

View File

@ -10,8 +10,9 @@ import (
const ( const (
// OrchestrationIdentifier identifier string for provider orchestration // OrchestrationIdentifier identifier string for provider orchestration
OrchestrationIdentifier = "containerd" OrchestrationIdentifier = "containerd"
// ProviderName name of the provider // ProviderName name of the provider
ProviderName = "faas-containerd" ProviderName = "faasd"
) )
//MakeInfoHandler creates handler for /system/info endpoint //MakeInfoHandler creates handler for /system/info endpoint

View File

@ -53,8 +53,11 @@ func Remove(ctx context.Context, client *containerd.Client, name string) error {
return nil return nil
} }
// From Stellar // Adapted from Stellar - https://github.com/stellar
func killTask(ctx context.Context, task containerd.Task) error { func killTask(ctx context.Context, task containerd.Task) error {
killTimeout := 30 * time.Second
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
wg.Add(1) wg.Add(1)
var err error var err error
@ -69,11 +72,12 @@ func killTask(ctx context.Context, task containerd.Task) error {
if err := task.Kill(ctx, unix.SIGTERM, containerd.WithKillAll); err != nil { if err := task.Kill(ctx, unix.SIGTERM, containerd.WithKillAll); err != nil {
log.Printf("error killing container task: %s", err) log.Printf("error killing container task: %s", err)
} }
select { select {
case <-wait: case <-wait:
task.Delete(ctx) task.Delete(ctx)
return return
case <-time.After(5 * time.Second): case <-time.After(killTimeout):
if err := task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil { if err := task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil {
log.Printf("error force killing container task: %s", err) log.Printf("error force killing container task: %s", err)
} }