Skip to content

Commit

Permalink
Use version package to track all versions
Browse files Browse the repository at this point in the history
* Server, bindings, and CLI all now pull version information from version
package.
* Current /libpod API version slaved to podman/libpod Version
* Bindings validate against libpod API Minimal version
* Remove pkg/bindings/bindings.go and updated tests

Fixes: #9207

Signed-off-by: Jhon Honce <[email protected]>
  • Loading branch information
jwhonce committed Mar 4, 2021
1 parent 87e2056 commit f86d641
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 154 deletions.
6 changes: 3 additions & 3 deletions libpod/define/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strconv"
"time"

podmanVersion "github.com/containers/podman/v3/version"
"github.com/containers/podman/v3/version"
)

// Overwritten at build time
Expand Down Expand Up @@ -42,8 +42,8 @@ func GetVersion() (Version, error) {
}
}
return Version{
APIVersion: podmanVersion.APIVersion.String(),
Version: podmanVersion.Version.String(),
APIVersion: version.APIVersion[version.Libpod][version.CurrentAPI].String(),
Version: version.Version.String(),
GoVersion: runtime.Version(),
GitCommit: gitCommit,
BuiltTime: time.Unix(buildTime, 0).Format(time.ANSIC),
Expand Down
9 changes: 5 additions & 4 deletions pkg/api/handlers/compat/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/version"
docker "github.com/docker/docker/api/types"
"github.com/pkg/errors"
)
Expand All @@ -35,20 +36,20 @@ func VersionHandler(w http.ResponseWriter, r *http.Request) {
Name: "Podman Engine",
Version: versionInfo.Version,
Details: map[string]string{
"APIVersion": utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String(),
"APIVersion": version.APIVersion[version.Libpod][version.CurrentAPI].String(),
"Arch": goRuntime.GOARCH,
"BuildTime": time.Unix(versionInfo.Built, 0).Format(time.RFC3339),
"Experimental": "true",
"GitCommit": versionInfo.GitCommit,
"GoVersion": versionInfo.GoVersion,
"KernelVersion": infoData.Host.Kernel,
"MinAPIVersion": utils.APIVersion[utils.LibpodTree][utils.MinimalAPIVersion].String(),
"MinAPIVersion": version.APIVersion[version.Libpod][version.MinimalAPI].String(),
"Os": goRuntime.GOOS,
},
}}

apiVersion := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
minVersion := utils.APIVersion[utils.CompatTree][utils.MinimalAPIVersion]
apiVersion := version.APIVersion[version.Compat][version.CurrentAPI]
minVersion := version.APIVersion[version.Compat][version.MinimalAPI]

utils.WriteResponse(w, http.StatusOK, entities.ComponentVersion{
Version: docker.Version{
Expand Down
45 changes: 5 additions & 40 deletions pkg/api/handlers/utils/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,14 @@ import (
"unsafe"

"github.com/blang/semver"
"github.com/containers/podman/v3/version"
"github.com/gorilla/mux"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

type (
// VersionTree determines which API endpoint tree for version
VersionTree int
// VersionLevel determines which API level, current or something from the past
VersionLevel int
)

const (
// LibpodTree supports Libpod endpoints
LibpodTree = VersionTree(iota)
// CompatTree supports Libpod endpoints
CompatTree

// CurrentAPIVersion announces what is the current API level
CurrentAPIVersion = VersionLevel(iota)
// MinimalAPIVersion announces what is the oldest API level supported
MinimalAPIVersion
)

var (
// See https://docs.docker.com/engine/api/v1.40/
// libpod compat handlers are expected to honor docker API versions

// APIVersion provides the current and minimal API versions for compat and libpod endpoint trees
// Note: GET|HEAD /_ping is never versioned and provides the API-Version and Libpod-API-Version headers to allow
// clients to shop for the Version they wish to support
APIVersion = map[VersionTree]map[VersionLevel]semver.Version{
LibpodTree: {
CurrentAPIVersion: semver.MustParse("3.0.0"),
MinimalAPIVersion: semver.MustParse("3.0.0"),
},
CompatTree: {
CurrentAPIVersion: semver.MustParse("1.40.0"),
MinimalAPIVersion: semver.MustParse("1.24.0"),
},
}

// ErrVersionNotGiven returned when version not given by client
ErrVersionNotGiven = errors.New("version not given in URL path")
// ErrVersionNotSupported returned when given version is too old
Expand Down Expand Up @@ -98,14 +63,14 @@ func SupportedVersion(r *http.Request, condition string) (semver.Version, error)
// SupportedVersionWithDefaults validates that the version provided by client valid is supported by server
// minimal API version <= client path version <= maximum API version focused on the endpoint tree from URL
func SupportedVersionWithDefaults(r *http.Request) (semver.Version, error) {
tree := CompatTree
tree := version.Compat
if IsLibpodRequest(r) {
tree = LibpodTree
tree = version.Libpod
}

return SupportedVersion(r,
fmt.Sprintf(">=%s <=%s", APIVersion[tree][MinimalAPIVersion].String(),
APIVersion[tree][CurrentAPIVersion].String()))
fmt.Sprintf(">=%s <=%s", version.APIVersion[tree][version.MinimalAPI].String(),
version.APIVersion[tree][version.CurrentAPI].String()))
}

// WriteResponse encodes the given value as JSON or string and renders it for http client
Expand Down
5 changes: 3 additions & 2 deletions pkg/api/handlers/utils/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import (
"net/http/httptest"
"testing"

"github.com/containers/podman/v3/version"
"github.com/gorilla/mux"
)

func TestSupportedVersion(t *testing.T) {
req, err := http.NewRequest("GET",
fmt.Sprintf("/v%s/libpod/testing/versions", APIVersion[LibpodTree][CurrentAPIVersion]),
fmt.Sprintf("/v%s/libpod/testing/versions", version.APIVersion[version.Libpod][version.CurrentAPI]),
nil)
if err != nil {
t.Fatal(err)
}
req = mux.SetURLVars(req, map[string]string{"version": APIVersion[LibpodTree][CurrentAPIVersion].String()})
req = mux.SetURLVars(req, map[string]string{"version": version.APIVersion[version.Libpod][version.CurrentAPI].String()})

rr := httptest.NewRecorder()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
7 changes: 4 additions & 3 deletions pkg/api/server/handler_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/version"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -55,10 +56,10 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
c = context.WithValue(c, "idletracker", s.idleTracker) // nolint
r = r.WithContext(c)

cv := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
cv := version.APIVersion[version.Compat][version.CurrentAPI]
w.Header().Set("API-Version", fmt.Sprintf("%d.%d", cv.Major, cv.Minor))

lv := utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String()
lv := version.APIVersion[version.Libpod][version.CurrentAPI].String()
w.Header().Set("Libpod-API-Version", lv)
w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")

Expand All @@ -72,5 +73,5 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
// VersionedPath prepends the version parsing code
// any handler may override this default when registering URL(s)
func VersionedPath(p string) string {
return "/v{version:[0-9][0-9.]*}" + p
return "/v{version:[0-9][0-9A-Za-z.-]*}" + p
}
26 changes: 0 additions & 26 deletions pkg/bindings/bindings.go

This file was deleted.

10 changes: 6 additions & 4 deletions pkg/bindings/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/blang/semver"
"github.com/containers/podman/v3/pkg/terminal"
"github.com/containers/podman/v3/version"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand All @@ -25,7 +26,7 @@ var (
BasePath = &url.URL{
Scheme: "http",
Host: "d",
Path: "/v" + APIVersion.String() + "/libpod",
Path: "/v" + version.APIVersion[version.Libpod][version.CurrentAPI].String() + "/libpod",
}
)

Expand Down Expand Up @@ -168,15 +169,16 @@ func pingNewConnection(ctx context.Context) error {
return err
}

switch APIVersion.Compare(versionSrv) {
switch version.APIVersion[version.Libpod][version.MinimalAPI].Compare(versionSrv) {
case -1, 0:
// Server's job when Client version is equal or older
return nil
case 1:
return errors.Errorf("server API version is too old. Client %q server %q", APIVersion.String(), versionSrv.String())
return errors.Errorf("server API version is too old. Client %q server %q",
version.APIVersion[version.Libpod][version.MinimalAPI].String(), versionSrv.String())
}
}
return errors.Errorf("ping response was %q", response.StatusCode)
return errors.Errorf("ping response was %d", response.StatusCode)
}

func sshClient(_url *url.URL, secure bool, passPhrase string, identity string) (Connection, error) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/bindings/test/attach_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var _ = Describe("Podman containers attach", func() {

It("can run top in container", func() {
name := "TopAttachTest"
id, err := bt.RunTopContainer(&name, nil, nil)
id, err := bt.RunTopContainer(&name, nil)
Expect(err).ShouldNot(HaveOccurred())

tickTock := time.NewTimer(2 * time.Second)
Expand Down
4 changes: 2 additions & 2 deletions pkg/bindings/test/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,14 @@ func (b *bindingTest) restoreImageFromCache(i testImage) {

// Run a container within or without a pod
// and add or append the alpine image to it
func (b *bindingTest) RunTopContainer(containerName *string, insidePod *bool, podName *string) (string, error) {
func (b *bindingTest) RunTopContainer(containerName *string, podName *string) (string, error) {
s := specgen.NewSpecGenerator(alpine.name, false)
s.Terminal = false
s.Command = []string{"/usr/bin/top"}
if containerName != nil {
s.Name = *containerName
}
if insidePod != nil && podName != nil {
if podName != nil {
s.Pod = *podName
}
ctr, err := containers.CreateWithSpec(b.conn, s, nil)
Expand Down
Loading

0 comments on commit f86d641

Please sign in to comment.