Skip to content

Commit

Permalink
Merge pull request #6 from jwhonce/wip/apiv2
Browse files Browse the repository at this point in the history
Initial commit on compatible API
  • Loading branch information
baude authored Nov 1, 2019
2 parents 2dae257 + 7d7a179 commit da8ec26
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 0 deletions.
41 changes: 41 additions & 0 deletions cmd/service/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"context"
"time"

"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/pkg/serviceapi"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

func initConfig() {
// we can do more stuff in here.
}

func main() {
cobra.OnInitialize(initConfig)

var cancel context.CancelFunc
_, cancel = context.WithTimeout(context.Background(), time.Duration(50)*time.Millisecond)
defer cancel()

config := cliconfig.PodmanCommand{
Command: &cobra.Command{},
InputArgs: []string{},
GlobalFlags: cliconfig.MainFlags{},
Remote: false,
}
// Create a single runtime for http
runtime, err := libpodruntime.GetRuntimeDisableFDs(context.Background(), &config)
if err != nil {
log.Panicf("error creating libpod runtime: %s", err)
}
defer runtime.DeferredShutdown(false)

server, _ := serviceapi.NewServer(runtime)
_ = server.Serve()
defer server.Shutdown()
}
114 changes: 114 additions & 0 deletions pkg/serviceapi/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package serviceapi

import (
"context"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/containers/libpod/libpod"
log "github.com/sirupsen/logrus"

"github.com/coreos/go-systemd/activation"
)

type HttpServer struct {
*http.Server
done chan struct{}
listener net.Listener
}

var libpodRuntime *libpod.Runtime

func NewServer(runtime *libpod.Runtime) (*HttpServer, error) {
libpodRuntime = runtime

listeners, err := activation.Listeners()
if err != nil {
log.Panicf("Cannot retrieve listeners: %s", err)
}
if len(listeners) != 1 {
log.Panicf("unexpected number of socket activation (%d != 1)", len(listeners))
}

done := make(chan struct{})
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

server := &http.Server{}
go func() {
<-quit
log.Debugf("HttpServer is shutting down")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.SetKeepAlivesEnabled(false)
if err := server.Shutdown(ctx); err != nil {
log.Panicf("cannot gracefully shut down the http server: %s", err)
}
close(done)
}()

// TODO: build this into a map...
http.Handle("/v1.24/images/json", serviceHandler(images))
http.Handle("/v1.24/containers/json", serviceHandler(containers))
return &HttpServer{server, done, listeners[0]}, nil
}

func (s *HttpServer) Serve() error {
err := http.Serve(s.listener, nil)
if err != nil {
log.Panicf("Cannot start server: %s", err)
}
<-s.done
return nil
}

func (s *HttpServer) Shutdown() error {
<-s.done
return nil
}

func (s *HttpServer) Close() error {
return s.Close()
}

type serviceHandler func(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime)

func (h serviceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h(w, r, libpodRuntime)
}

func images(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime) {
contentType := r.Header.Get("Content-Type")
if contentType != "" && contentType != "application/json" {
http.Error(w,
fmt.Sprintf("%s is not a supported Content-Type", r.Header.Get("Content-Type")),
http.StatusUnsupportedMediaType)
return
}

images, err := runtime.ImageRuntime().GetImages()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

buffer, err := json.Marshal(images)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
io.WriteString(w, string(buffer))
}

func containers(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime) {
http.NotFound(w, r)
}

0 comments on commit da8ec26

Please sign in to comment.