Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 24, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Documentation/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ The API service allows clients to list and inspect pods and images running under
## Misc

* [version](subcommands/version.md)
* [config](subcommands/config.md)

## Global Options

Expand Down
125 changes: 125 additions & 0 deletions Documentation/subcommands/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# rkt config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paging @joshix for doc review.


The `config` subcommand prints the configuration of each rkt stage in JSON on the standard output.

## Structure

The general structure is a simple hierarchy consisting of the following top-level element:

```
{
"stage0": [...]
}
```

The entry "stage0" refers to stage-specific configuration; "stage1" is currently left out intentionally because its configuration subsystem is subject to change. The generated output are valid configuration entries as specified in the configuration documentation.

The "stage0" entry contains subentries of rktKind "auth", "dockerAuth", "paths", and "stage1". Note that the `config` subcommand will output separate entries per "auth" domain and separate entries per "dockerAuth" registry. While it is possible to specify an array of strings in the input configuration rkt internally merges configuration state from different directories potentially creating multiple entries.

Consider the following system configuration:
```
$ cat /etc/rkt/auth.d/basic.json
{
"rktKind": "auth",
"rktVersion": "v1",
"domains": [
"foo.com",
"bar.com",
"baz.com"
],
"type": "basic",
"credentials": { "user": "sysUser", "password": "sysPassword" }
}
```

And the following user configuration:
```
$ ~/.config/rkt/auth.d/basic.json
{
"rktKind": "auth",
"rktVersion": "v1",
"domains": [
"foo.com"
],
"type": "basic",
"credentials": { "user": "user", "password": "password" }
}
```

The `config` subcommand would generate the following separate merged entries:
```
{
"stage0": [
{
"rktVersion": "v1",
"rktKind": "auth",
"domains": [ "bar.com" ],
"type": "basic",
"credentials": { "user": "sysUser", "password": "sysPassword" }
},
{
"rktVersion": "v1",
"rktKind": "auth",
"domains": [ "baz.com" ],
"type": "basic",
"credentials": { "user": "sysUser", "password": "sysPassword" }
},
{
"rktVersion": "v1",
"rktKind": "auth",
"domains": [ "foo.com" ],
"type": "basic",
"credentials": { "user": "user", "password": "password" }
}
]
}
```

In the example given above the user configuration entry for the domain "foo.com" overrides the system configuration entry leaving the entries "bar.com" and "baz.com" unchanged. The `config` subcommand output creates three separate entries for "foo.com", "bar.com", and "baz.com".

Note: While the "bar.com", and "baz.com" entries in the example given above could be merged into one entry they are still being printed separate. This behavior is subject to change, future implementations may provide a merged output.

## Example

```
$ rkt config
{
"stage0": [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOB notes:

  • define top-level struct, as this is new
  • explain why we are printing each entry separately (even if the input config was deduplicated)
  • explain oauth/basic mutual incompatibility and override semantics

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, please capture everything from the design doc in here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed OOB notes. I could not reproduce the oauth/basic mutual incompatibility, I mixed up the already documented override semantics of system/user directories.

{
"rktVersion": "v1",
"rktKind": "auth",
"domains": [
"bar.com"
],
"type": "oauth",
"credentials": {
"token": "someToken"
}
},
{
"rktVersion": "v1",
"rktKind": "auth",
"domains": [
"foo.com"
],
"type": "basic",
"credentials": {
"user": "user",
"password": "userPassword"
}
},
{
"rktVersion": "v1",
"rktKind": "paths",
"data": "/var/lib/rkt",
"stage1-images": "/usr/lib/rkt"
},
{
"rktVersion": "v1",
"rktKind": "stage1",
"name": "coreos.com/rkt/stage1-coreos",
"version": "0.15.0+git",
"location": "/usr/libexec/rkt/stage1-coreos.aci"
}
]
}
51 changes: 51 additions & 0 deletions rkt/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2016 The rkt Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"encoding/json"

"github.com/spf13/cobra"
)

var (
cmdConfig = &cobra.Command{
Use: "config",
Short: "Print configuration for each stage in JSON format",
Long: `The output will be parsable JSON with "stage0" and stage1" as keys and rkt configuration entries as values.
The generated configuration entries resemble the original rkt configuration format.`,
Run: runWrapper(runConfig),
}
)

func init() {
cmdRkt.AddCommand(cmdConfig)
}

func runConfig(cmd *cobra.Command, args []string) int {
config, err := getConfig()
if err != nil {
stderr.PrintE("cannot get configuration", err)
return 1
}

b, err := json.Marshal(config)
if err != nil {
stderr.PanicE("error marshaling configuration", err)
}

stdout.Print(string(b))
return 0
}
14 changes: 6 additions & 8 deletions rkt/config/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,25 @@ func init() {
}

type basicAuthHeaderer struct {
user string
password string
auth basicV1
}

func (h *basicAuthHeaderer) Header() http.Header {
headers := make(http.Header)
creds := []byte(fmt.Sprintf("%s:%s", h.user, h.password))
creds := []byte(fmt.Sprintf("%s:%s", h.auth.User, h.auth.Password))
encodedCreds := base64.StdEncoding.EncodeToString(creds)
headers.Add(authHeader, "Basic "+encodedCreds)

return headers
}

type oAuthBearerTokenHeaderer struct {
token string
auth oauthV1
}

func (h *oAuthBearerTokenHeaderer) Header() http.Header {
headers := make(http.Header)
headers.Add(authHeader, "Bearer "+h.token)
headers.Add(authHeader, "Bearer "+h.auth.Token)

return headers
}
Expand Down Expand Up @@ -124,8 +123,7 @@ func (p *authV1JsonParser) getBasicV1Headerer(raw json.RawMessage) (Headerer, er
return nil, err
}
return &basicAuthHeaderer{
user: basic.User,
password: basic.Password,
auth: basic,
}, nil
}

Expand All @@ -138,7 +136,7 @@ func (p *authV1JsonParser) getOAuthV1Headerer(raw json.RawMessage) (Headerer, er
return nil, fmt.Errorf("no oauth bearer token specified")
}
return &oAuthBearerTokenHeaderer{
token: oauth.Token,
auth: oauth,
}, nil
}

Expand Down
89 changes: 87 additions & 2 deletions rkt/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package config

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
Expand All @@ -37,8 +38,8 @@ type Headerer interface {
// BasicCredentials holds typical credentials used for authentication
// (user and password). Used for fetching docker images.
type BasicCredentials struct {
User string
Password string
User string `json:"user"`
Password string `json:"password"`
}

// ConfigurablePaths holds various paths defined in the configuration.
Expand All @@ -64,6 +65,90 @@ type Config struct {
Stage1 Stage1Data
}

// MarshalJSON marshals the config for user output.
func (c *Config) MarshalJSON() ([]byte, error) {
stage0 := []interface{}{}

for host, auth := range c.AuthPerHost {
var typ string
var credentials interface{}

switch h := auth.(type) {
case *basicAuthHeaderer:
typ = "basic"
credentials = h.auth
case *oAuthBearerTokenHeaderer:
typ = "oauth"
credentials = h.auth
default:
return nil, errors.New("unknown headerer type")
}

auth := struct {
RktVersion string `json:"rktVersion"`
RktKind string `json:"rktKind"`
Domains []string `json:"domains"`
Type string `json:"type"`
Credentials interface{} `json:"credentials"`
}{
RktVersion: "v1",
RktKind: "auth",
Domains: []string{host},
Type: typ,
Credentials: credentials,
}

stage0 = append(stage0, auth)
}

for registry, credentials := range c.DockerCredentialsPerRegistry {
dockerAuth := struct {
RktVersion string `json:"rktVersion"`
RktKind string `json:"rktKind"`
Registries []string `json:"registries"`
Credentials BasicCredentials `json:"credentials"`
}{
RktVersion: "v1",
RktKind: "dockerAuth",
Registries: []string{registry},
Credentials: credentials,
}

stage0 = append(stage0, dockerAuth)
}

paths := struct {
RktVersion string `json:"rktVersion"`
RktKind string `json:"rktKind"`
Data string `json:"data"`
Stage1Images string `json:"stage1-images"`
}{
RktVersion: "v1",
RktKind: "paths",
Data: c.Paths.DataDir,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krnowak @alban this will print a different path if the user specified --dir, see https://github.com/coreos/rkt/blob/master/rkt/rkt.go#L261, what do you think, use the calculateDataDir result instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'd keep it like that.

Stage1Images: c.Paths.Stage1ImagesDir,
}

stage1 := struct {
RktVersion string `json:"rktVersion"`
RktKind string `json:"rktKind"`
Name string `json:"name"`
Version string `json:"version"`
Location string `json:"location"`
}{
RktVersion: "v1",
RktKind: "stage1",
Name: c.Stage1.Name,
Version: c.Stage1.Version,
Location: c.Stage1.Location,
}

stage0 = append(stage0, paths, stage1)

data := map[string]interface{}{"stage0": stage0}
return json.Marshal(data)
}

type configParser interface {
parse(config *Config, raw []byte) error
}
Expand Down
8 changes: 8 additions & 0 deletions rkt/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func TestAuthConfigFormat(t *testing.T) {
t.Error("Got unexpected results\nResult:\n", result, "\n\nExpected:\n", tt.expected)
}
}

if _, err := json.Marshal(cfg); err != nil {
t.Errorf("error marshaling config %v", err)
}
}
}

Expand Down Expand Up @@ -118,6 +122,10 @@ func TestDockerAuthConfigFormat(t *testing.T) {
t.Error("Got unexpected results\nResult:\n", result, "\n\nExpected:\n", tt.expected)
}
}

if _, err := json.Marshal(cfg); err != nil {
t.Errorf("error marshaling config %v", err)
}
}
}

Expand Down