mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 07:20:13 +00:00
Merge pull request #2246 from lavalamp/fix2
Fix unversioned output being passed to -template
This commit is contained in:
commit
0ee7d5cc75
@ -92,7 +92,7 @@ function kube-up {
|
||||
local count="0"
|
||||
until [[ "$count" == "1" ]]; do
|
||||
local minions
|
||||
minions=$("${KUBE_ROOT}/cluster/kubecfg.sh" -template '{{range.Items}}{{.Name}}:{{end}}' list minions)
|
||||
minions=$("${KUBE_ROOT}/cluster/kubecfg.sh" -template '{{range.items}}{{.id}}:{{end}}' list minions)
|
||||
count=$(echo $minions | grep -c "${MINION_NAMES[i]}") || {
|
||||
printf "."
|
||||
sleep 2
|
||||
|
@ -33,7 +33,7 @@ detect-master > /dev/null
|
||||
detect-minions > /dev/null
|
||||
|
||||
MINIONS_FILE=/tmp/minions
|
||||
"${KUBE_ROOT}/cluster/kubecfg.sh" -template $'{{range.Items}}{{.Name}}\n{{end}}' list minions > ${MINIONS_FILE}
|
||||
"${KUBE_ROOT}/cluster/kubecfg.sh" -template $'{{range.items}}{{.id}}\n{{end}}' list minions > ${MINIONS_FILE}
|
||||
|
||||
# On vSphere, use minion IPs as their names
|
||||
if [[ "${KUBERNETES_PROVIDER}" == "vsphere" ]]; then
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
@ -324,14 +323,12 @@ func getPrinter() kubecfg.ResourcePrinter {
|
||||
} else {
|
||||
data = []byte(*templateStr)
|
||||
}
|
||||
tmpl, err := template.New("output").Parse(string(data))
|
||||
var err error
|
||||
printer, err = kubecfg.NewTemplatePrinter(data)
|
||||
if err != nil {
|
||||
glog.Fatalf("Error parsing template %s, %v\n", string(data), err)
|
||||
glog.Fatalf("Error '%v' parsing template:\n'%s'", err, string(data))
|
||||
return nil
|
||||
}
|
||||
printer = &kubecfg.TemplatePrinter{
|
||||
Template: tmpl,
|
||||
}
|
||||
default:
|
||||
printer = humanReadablePrinter()
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ function teardown() {
|
||||
|
||||
trap "teardown" EXIT
|
||||
|
||||
pod_id_list=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' -l replicationController=my-hostname list pods)
|
||||
pod_id_list=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' -l replicationController=my-hostname list pods)
|
||||
# Pod turn up on a clean cluster can take a while for the docker image pull.
|
||||
all_running=0
|
||||
for i in $(seq 1 24); do
|
||||
@ -45,7 +45,7 @@ for i in $(seq 1 24); do
|
||||
sleep 5
|
||||
all_running=1
|
||||
for id in $pod_id_list; do
|
||||
current_status=$($KUBECFG -template '{{.CurrentState.Status}}' get pods/$id) || true
|
||||
current_status=$($KUBECFG -template '{{.currentState.status}}' get pods/$id) || true
|
||||
if [[ "$current_status" != "Running" ]]; then
|
||||
all_running=0
|
||||
break
|
||||
@ -69,7 +69,7 @@ sleep 5
|
||||
|
||||
# Verify that something is listening.
|
||||
for id in ${pod_id_list}; do
|
||||
ip=$($KUBECFG -template '{{.CurrentState.HostIP}}' get pods/$id)
|
||||
ip=$($KUBECFG -template '{{.currentState.hostIP}}' get pods/$id)
|
||||
echo "Trying to reach server that should be running at ${ip}:8080..."
|
||||
ok=0
|
||||
for i in $(seq 1 5); do
|
||||
|
@ -35,7 +35,7 @@ $KUBECFG -c "${GUESTBOOK}/redis-slave-controller.json" create /replicationContro
|
||||
|
||||
sleep 5
|
||||
|
||||
POD_LIST_1=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' list pods)
|
||||
POD_LIST_1=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' list pods)
|
||||
echo "Pods running: ${POD_LIST_1}"
|
||||
|
||||
$KUBECFG stop redisSlaveController
|
||||
@ -45,7 +45,7 @@ $KUBECFG rm redisSlaveController
|
||||
$KUBECFG delete services/redismaster
|
||||
$KUBECFG delete pods/redis-master-2
|
||||
|
||||
POD_LIST_2=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' list pods)
|
||||
POD_LIST_2=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' list pods)
|
||||
echo "Pods running after shutdown: ${POD_LIST_2}"
|
||||
|
||||
exit 0
|
||||
|
@ -69,7 +69,7 @@ function query_pods() {
|
||||
local i
|
||||
for i in $(seq 1 10); do
|
||||
pods_unsorted=($(${KUBECFG} \
|
||||
'-template={{range.Items}}{{.Name}} {{end}}' \
|
||||
'-template={{range.items}}{{.id}} {{end}}' \
|
||||
-l name="$1" list pods))
|
||||
found="${#pods_unsorted[*]}"
|
||||
if [[ "${found}" == "$2" ]]; then
|
||||
@ -103,7 +103,7 @@ function wait_for_pods() {
|
||||
echo "Waiting for ${pods_needed} pods to become 'running'"
|
||||
pods_needed="$2"
|
||||
for id in ${pods_sorted}; do
|
||||
status=$(${KUBECFG} -template '{{.CurrentState.Status}}' get "pods/${id}")
|
||||
status=$(${KUBECFG} -template '{{.currentState.status}}' get "pods/${id}")
|
||||
if [[ "${status}" == "Running" ]]; then
|
||||
pods_needed=$((pods_needed-1))
|
||||
fi
|
||||
@ -213,9 +213,9 @@ svc1_pods=$(query_pods "${svc1_name}" "${svc1_count}")
|
||||
svc2_pods=$(query_pods "${svc2_name}" "${svc2_count}")
|
||||
|
||||
# Get the portal IPs.
|
||||
svc1_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc1_name}")
|
||||
svc1_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc1_name}")
|
||||
test -n "${svc1_ip}" || error "Service1 IP is blank"
|
||||
svc2_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc2_name}")
|
||||
svc2_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc2_name}")
|
||||
test -n "${svc2_ip}" || error "Service2 IP is blank"
|
||||
if [[ "${svc1_ip}" == "${svc2_ip}" ]]; then
|
||||
error "Portal IPs conflict: ${svc1_ip}"
|
||||
@ -272,7 +272,7 @@ wait_for_pods "${svc3_name}" "${svc3_count}"
|
||||
svc3_pods=$(query_pods "${svc3_name}" "${svc3_count}")
|
||||
|
||||
# Get the portal IP.
|
||||
svc3_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc3_name}")
|
||||
svc3_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc3_name}")
|
||||
test -n "${svc3_ip}" || error "Service3 IP is blank"
|
||||
if [[ "${svc3_ip}" != "${svc1_ip}" ]]; then
|
||||
error "Portal IPs not resued: ${svc3_ip} != ${svc1_ip}"
|
||||
@ -325,7 +325,7 @@ wait_for_pods "${svc4_name}" "${svc4_count}"
|
||||
svc4_pods=$(query_pods "${svc4_name}" "${svc4_count}")
|
||||
|
||||
# Get the portal IP.
|
||||
svc4_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc4_name}")
|
||||
svc4_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc4_name}")
|
||||
test -n "${svc4_ip}" || error "Service4 IP is blank"
|
||||
if [[ "${svc4_ip}" == "${svc2_ip}" || "${svc4_ip}" == "${svc3_ip}" ]]; then
|
||||
error "Portal IPs conflict: ${svc4_ip}"
|
||||
|
@ -38,7 +38,7 @@ function validate() {
|
||||
sleep 2
|
||||
|
||||
local pod_id_list
|
||||
pod_id_list=($($KUBECFG -template='{{range.Items}}{{.Name}} {{end}}' -l name="${CONTROLLER_NAME}" list pods))
|
||||
pod_id_list=($($KUBECFG -template='{{range.items}}{{.id}} {{end}}' -l name="${CONTROLLER_NAME}" list pods))
|
||||
|
||||
echo " ${#pod_id_list[@]} out of ${num_replicas} created"
|
||||
|
||||
@ -61,7 +61,7 @@ function validate() {
|
||||
# currently always set to a zero time.
|
||||
#
|
||||
# You can read about the syntax here: http://golang.org/pkg/text/template/
|
||||
template_string="{{and ((index .CurrentState.Info \"${CONTROLLER_NAME}\").State.Running) .CurrentState.Info.net.State.Running}}"
|
||||
template_string="{{and ((index .currentState.info \"${CONTROLLER_NAME}\").state.running.startedAt) .currentState.info.net.state.running.startedAt}}"
|
||||
current_status=$($KUBECFG -template="${template_string}" get "pods/$id") || {
|
||||
if [[ $current_status =~ "pod \"${id}\" not found" ]]; then
|
||||
echo " $id no longer exists"
|
||||
@ -73,12 +73,12 @@ function validate() {
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$current_status" != "{0001-01-01 00:00:00 +0000 UTC}" ]]; then
|
||||
if [[ "$current_status" != "0001-01-01T00:00:00Z" ]]; then
|
||||
echo " $id is created but not running"
|
||||
continue
|
||||
fi
|
||||
|
||||
template_string="{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").Image}}"
|
||||
template_string="{{(index .currentState.info \"${CONTROLLER_NAME}\").image}}"
|
||||
current_image=$($KUBECFG -template="${template_string}" get "pods/$id")
|
||||
if [[ "$current_image" != "${DOCKER_HUB_USER}/update-demo:${container_image_version}" ]]; then
|
||||
echo " ${id} is created but running wrong image"
|
||||
@ -86,7 +86,7 @@ function validate() {
|
||||
fi
|
||||
|
||||
|
||||
host_ip=$($KUBECFG -template='{{.CurrentState.HostIP}}' get pods/$id)
|
||||
host_ip=$($KUBECFG -template='{{.currentState.hostIP}}' get pods/$id)
|
||||
curl -s --max-time 5 --fail http://${host_ip}:8080/data.json \
|
||||
| grep -q ${container_image_version} || {
|
||||
echo " ${id} is running the right image but curl to contents failed or returned wrong info"
|
||||
|
21
hack/e2e.go
21
hack/e2e.go
@ -40,6 +40,9 @@ var (
|
||||
tests = flag.String("tests", "", "Run only tests in hack/e2e-suite matching this glob. Ignored if -test is set.")
|
||||
root = flag.String("root", absOrDie(filepath.Clean(filepath.Join(path.Base(os.Args[0]), ".."))), "Root directory of kubernetes repository.")
|
||||
verbose = flag.Bool("v", false, "If true, print all command output.")
|
||||
|
||||
cfgCmd = flag.String("cfg", "", "If nonempty, pass this as an argument, and call kubecfg. Implies -v.")
|
||||
ctlCmd = flag.String("ctl", "", "If nonempty, pass this as an argument, and call kubectl. Implies -v. (-test, -cfg, -ctl are mutually exclusive)")
|
||||
)
|
||||
|
||||
var signals = make(chan os.Signal, 100)
|
||||
@ -87,18 +90,24 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
failed, passed := []string{}, []string{}
|
||||
if *tests != "" {
|
||||
failed, passed = Test()
|
||||
failure := false
|
||||
switch {
|
||||
case *cfgCmd != "":
|
||||
failure = !runBash("'kubecfg "+*cfgCmd+"'", "$KUBECFG "+*cfgCmd)
|
||||
case *ctlCmd != "":
|
||||
failure = !runBash("'kubectl "+*ctlCmd+"'", "$KUBECFG "+*ctlCmd)
|
||||
case *tests != "":
|
||||
failed, passed := Test()
|
||||
log.Printf("Passed tests: %v", passed)
|
||||
log.Printf("Failed tests: %v", failed)
|
||||
failure = len(failed) > 0
|
||||
}
|
||||
|
||||
if *down {
|
||||
TearDown()
|
||||
}
|
||||
|
||||
log.Printf("Passed tests: %v", passed)
|
||||
log.Printf("Failed tests: %v", failed)
|
||||
if len(failed) > 0 {
|
||||
if failure {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -100,12 +100,12 @@ kube::log::status "Testing kubectl(pods)"
|
||||
"${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
||||
"${kube_cmd[@]}" get pods "${kube_flags[@]}"
|
||||
"${kube_cmd[@]}" get pod redis-master-2 "${kube_flags[@]}"
|
||||
[[ "$("${kube_cmd[@]}" get pod redis-master-2 -o template --output-version=v1beta1 -t '{{ .ID }}' "${kube_flags[@]}")" == "redis-master-2" ]]
|
||||
[[ "$("${kube_cmd[@]}" get pod redis-master-2 -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master-2" ]]
|
||||
output_pod=$("${kube_cmd[@]}" get pod redis-master-2 -o json --output-version=v1beta1 "${kube_flags[@]}")
|
||||
"${kube_cmd[@]}" delete pod redis-master-2 "${kube_flags[@]}"
|
||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .Items }}' "${kube_flags[@]}") -eq 0 ]]
|
||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 0 ]]
|
||||
echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}"
|
||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .Items }}' "${kube_flags[@]}") -eq 1 ]]
|
||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 1 ]]
|
||||
"${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master-2"
|
||||
"${kube_cmd[@]}" describe pod redis-master-2 "${kube_flags[@]}" | grep -q 'Name:.*redis-master-2'
|
||||
"${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
||||
|
@ -319,19 +319,32 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
||||
|
||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||
type TemplatePrinter struct {
|
||||
Template *template.Template
|
||||
template *template.Template
|
||||
}
|
||||
|
||||
func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||
t, err := template.New("output").Parse(string(tmpl))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &TemplatePrinter{t}, nil
|
||||
}
|
||||
|
||||
// Print parses the data as JSON, and re-formats it with the Go Template.
|
||||
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
||||
obj, err := latest.Codec.Decode(data)
|
||||
obj := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.PrintObj(obj, w)
|
||||
return t.template.Execute(w, obj)
|
||||
}
|
||||
|
||||
// PrintObj formats the obj with the Go Template.
|
||||
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
return t.Template.Execute(w, obj)
|
||||
data, err := latest.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.Print(data, w)
|
||||
}
|
||||
|
@ -161,3 +161,19 @@ func TestUnknownTypePrinting(t *testing.T) {
|
||||
t.Errorf("An error was expected from printing unknown type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||
// kind is always blank in memory and set on the wire
|
||||
printer, err := NewTemplatePrinter([]byte(`{{.kind}}`))
|
||||
if err != nil {
|
||||
t.Fatalf("tmpl fail: %v", err)
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||
if err != nil {
|
||||
t.Fatalf("print fail: %v", err)
|
||||
}
|
||||
if e, a := "Pod", string(buffer.Bytes()); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/golang/glog"
|
||||
@ -45,35 +46,26 @@ func GetPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (Re
|
||||
case "yaml":
|
||||
printer = &YAMLPrinter{}
|
||||
case "template":
|
||||
var data []byte
|
||||
if len(templateFile) == 0 {
|
||||
return nil, false, fmt.Errorf("template format specified but no template given")
|
||||
}
|
||||
tmpl, err := template.New("output").Parse(templateFile)
|
||||
var err error
|
||||
printer, err = NewTemplatePrinter([]byte(templateFile))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
||||
}
|
||||
printer = &TemplatePrinter{
|
||||
Template: tmpl,
|
||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", templateFile, err)
|
||||
}
|
||||
case "templatefile":
|
||||
var data []byte
|
||||
if len(templateFile) > 0 {
|
||||
var err error
|
||||
data, err = ioutil.ReadFile(templateFile)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err)
|
||||
}
|
||||
} else {
|
||||
if len(templateFile) == 0 {
|
||||
return nil, false, fmt.Errorf("templatefile format specified but no template file given")
|
||||
}
|
||||
tmpl, err := template.New("output").Parse(string(data))
|
||||
data, err := ioutil.ReadFile(templateFile)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err)
|
||||
}
|
||||
printer, err = NewTemplatePrinter(data)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
||||
}
|
||||
printer = &TemplatePrinter{
|
||||
Template: tmpl,
|
||||
}
|
||||
case "":
|
||||
printer = defaultPrinter
|
||||
versioned = false
|
||||
@ -323,12 +315,29 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
||||
|
||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||
type TemplatePrinter struct {
|
||||
Template *template.Template
|
||||
template *template.Template
|
||||
}
|
||||
|
||||
func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||
t, err := template.New("output").Parse(string(tmpl))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &TemplatePrinter{t}, nil
|
||||
}
|
||||
|
||||
// PrintObj formats the obj with the Go Template.
|
||||
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
return t.Template.Execute(w, obj)
|
||||
data, err := latest.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outObj := map[string]interface{}{}
|
||||
err = json.Unmarshal(data, &outObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.template.Execute(w, outObj)
|
||||
}
|
||||
|
||||
func tabbedString(f func(*tabwriter.Writer) error) (string, error) {
|
||||
|
@ -86,14 +86,17 @@ func TestPrintYAML(t *testing.T) {
|
||||
|
||||
func TestPrintTemplate(t *testing.T) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
printer, versioned, err := GetPrinter("template", "{{ .Name }}", nil)
|
||||
printer, versioned, err := GetPrinter("template", "{{.id}}", nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %#v", err)
|
||||
t.Fatalf("unexpected error: %#v", err)
|
||||
}
|
||||
if !versioned {
|
||||
t.Errorf("printer should be versioned")
|
||||
}
|
||||
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||
err = printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %#v", err)
|
||||
}
|
||||
if buf.String() != "foo" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
@ -204,3 +207,19 @@ func TestUnknownTypePrinting(t *testing.T) {
|
||||
t.Errorf("An error was expected from printing unknown type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||
// kind is always blank in memory and set on the wire
|
||||
printer, err := NewTemplatePrinter([]byte(`{{.kind}}`))
|
||||
if err != nil {
|
||||
t.Fatalf("tmpl fail: %v", err)
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||
if err != nil {
|
||||
t.Fatalf("print fail: %v", err)
|
||||
}
|
||||
if e, a := "Pod", string(buffer.Bytes()); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user