Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
9837a985
Commit
9837a985
authored
Apr 10, 2017
by
Chao Xu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move resource_helpers.go to a subpackage
parent
d9920c53
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
337 additions
and
629 deletions
+337
-629
BUILD
pkg/api/BUILD
+2
-9
BUILD
pkg/api/pod/BUILD
+4
-1
util.go
pkg/api/pod/util.go
+65
-1
resource.go
pkg/api/resource.go
+55
-0
BUILD
pkg/api/resource/BUILD
+18
-1
doc.go
pkg/api/resource/doc.go
+0
-21
resource_helpers.go
pkg/api/resource/resource_helpers.go
+112
-0
resource_helpers_test.go
pkg/api/resource/resource_helpers_test.go
+14
-50
resource_helpers.go
pkg/api/resource_helpers.go
+0
-270
BUILD
pkg/client/unversioned/BUILD
+1
-0
conditions.go
pkg/client/unversioned/conditions.go
+2
-1
BUILD
pkg/printers/internalversion/BUILD
+1
-0
describe.go
pkg/printers/internalversion/describe.go
+4
-3
BUILD
pkg/registry/core/pod/storage/BUILD
+1
-0
storage.go
pkg/registry/core/pod/storage/storage.go
+2
-1
resource.go
staging/src/k8s.io/client-go/pkg/api/resource.go
+55
-0
resource_helpers.go
staging/src/k8s.io/client-go/pkg/api/resource_helpers.go
+0
-270
BUILD
vendor/BUILD
+1
-1
No files found.
pkg/api/BUILD
View file @
9837a985
...
...
@@ -18,7 +18,7 @@ go_library(
"json.go",
"objectreference.go",
"register.go",
"resource
_helpers
.go",
"resource.go",
"taint.go",
"toleration.go",
"types.go",
...
...
@@ -43,16 +43,9 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"resource_helpers_test.go",
"taint_test.go",
],
srcs = ["taint_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
],
)
go_test(
...
...
pkg/api/pod/BUILD
View file @
9837a985
...
...
@@ -12,7 +12,10 @@ go_library(
name = "go_default_library",
srcs = ["util.go"],
tags = ["automanaged"],
deps = ["//pkg/api:go_default_library"],
deps = [
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
],
)
filegroup(
...
...
pkg/api/pod/util.go
View file @
9837a985
...
...
@@ -16,7 +16,10 @@ limitations under the License.
package
pod
import
"k8s.io/kubernetes/pkg/api"
import
(
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api"
)
// VisitPodSecretNames invokes the visitor function with the name of every secret
// referenced by the pod spec. If visitor returns false, visiting is short-circuited.
...
...
@@ -100,3 +103,64 @@ func visitContainerSecretNames(container *api.Container, visitor func(string) bo
}
return
true
}
// IsPodReady returns true if a pod is ready; false otherwise.
func
IsPodReady
(
pod
*
api
.
Pod
)
bool
{
return
IsPodReadyConditionTrue
(
pod
.
Status
)
}
// IsPodReadyConditionTrue retruns true if a pod is ready; false otherwise.
func
IsPodReadyConditionTrue
(
status
api
.
PodStatus
)
bool
{
condition
:=
GetPodReadyCondition
(
status
)
return
condition
!=
nil
&&
condition
.
Status
==
api
.
ConditionTrue
}
// GetPodReadyCondition extracts the pod ready condition from the given status and returns that.
// Returns nil if the condition is not present.
func
GetPodReadyCondition
(
status
api
.
PodStatus
)
*
api
.
PodCondition
{
_
,
condition
:=
GetPodCondition
(
&
status
,
api
.
PodReady
)
return
condition
}
// GetPodCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func
GetPodCondition
(
status
*
api
.
PodStatus
,
conditionType
api
.
PodConditionType
)
(
int
,
*
api
.
PodCondition
)
{
if
status
==
nil
{
return
-
1
,
nil
}
for
i
:=
range
status
.
Conditions
{
if
status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
i
,
&
status
.
Conditions
[
i
]
}
}
return
-
1
,
nil
}
// UpdatePodCondition updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if pod condition has changed or has been added.
func
UpdatePodCondition
(
status
*
api
.
PodStatus
,
condition
*
api
.
PodCondition
)
bool
{
condition
.
LastTransitionTime
=
metav1
.
Now
()
// Try to find this pod condition.
conditionIndex
,
oldCondition
:=
GetPodCondition
(
status
,
condition
.
Type
)
if
oldCondition
==
nil
{
// We are adding new pod condition.
status
.
Conditions
=
append
(
status
.
Conditions
,
*
condition
)
return
true
}
// We are updating an existing condition, so we need to check if it has changed.
if
condition
.
Status
==
oldCondition
.
Status
{
condition
.
LastTransitionTime
=
oldCondition
.
LastTransitionTime
}
isEqual
:=
condition
.
Status
==
oldCondition
.
Status
&&
condition
.
Reason
==
oldCondition
.
Reason
&&
condition
.
Message
==
oldCondition
.
Message
&&
condition
.
LastProbeTime
.
Equal
(
oldCondition
.
LastProbeTime
)
&&
condition
.
LastTransitionTime
.
Equal
(
oldCondition
.
LastTransitionTime
)
status
.
Conditions
[
conditionIndex
]
=
*
condition
// Return true if one of the fields have changed.
return
!
isEqual
}
pkg/api/resource.go
0 → 100644
View file @
9837a985
/*
Copyright 2017 The Kubernetes 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
api
import
(
"k8s.io/apimachinery/pkg/api/resource"
)
func
(
self
ResourceName
)
String
()
string
{
return
string
(
self
)
}
// Returns the CPU limit if specified.
func
(
self
*
ResourceList
)
Cpu
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceCPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
DecimalSI
}
}
// Returns the Memory limit if specified.
func
(
self
*
ResourceList
)
Memory
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceMemory
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
BinarySI
}
}
func
(
self
*
ResourceList
)
Pods
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourcePods
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
(
self
*
ResourceList
)
NvidiaGPU
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceNvidiaGPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
pkg/api/resource/BUILD
View file @
9837a985
...
...
@@ -5,12 +5,17 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["
doc
.go"],
srcs = ["
resource_helpers
.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
],
)
filegroup(
...
...
@@ -25,3 +30,15 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["resource_helpers_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
],
)
pkg/api/resource/doc.go
deleted
100644 → 0
View file @
d9920c53
/*
Copyright 2017 The Kubernetes 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 resource only exists until heapster rebases
// TODO genericapiserver remove this empty package. Godep fails without this because heapster relies
// on this package. This will allow us to start splitting packages, but will force
// heapster to update on their next kube rebase.
package
resource
pkg/api/resource/resource_helpers.go
0 → 100644
View file @
9837a985
/*
Copyright 2014 The Kubernetes 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
resource
import
(
"fmt"
"math"
"strconv"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/kubernetes/pkg/api"
)
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
// containers of the pod.
func
PodRequestsAndLimits
(
pod
*
api
.
Pod
)
(
reqs
map
[
api
.
ResourceName
]
resource
.
Quantity
,
limits
map
[
api
.
ResourceName
]
resource
.
Quantity
,
err
error
)
{
reqs
,
limits
=
map
[
api
.
ResourceName
]
resource
.
Quantity
{},
map
[
api
.
ResourceName
]
resource
.
Quantity
{}
for
_
,
container
:=
range
pod
.
Spec
.
Containers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
if
value
,
ok
:=
reqs
[
name
];
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
reqs
[
name
]
=
value
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
if
value
,
ok
:=
limits
[
name
];
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
limits
[
name
]
=
value
}
}
}
// init containers define the minimum of any resource
for
_
,
container
:=
range
pod
.
Spec
.
InitContainers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
value
,
ok
:=
reqs
[
name
]
if
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
value
,
ok
:=
limits
[
name
]
if
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
}
}
return
}
// ExtractContainerResourceValue extracts the value of a resource
// in an already known container
func
ExtractContainerResourceValue
(
fs
*
api
.
ResourceFieldSelector
,
container
*
api
.
Container
)
(
string
,
error
)
{
divisor
:=
resource
.
Quantity
{}
if
divisor
.
Cmp
(
fs
.
Divisor
)
==
0
{
divisor
=
resource
.
MustParse
(
"1"
)
}
else
{
divisor
=
fs
.
Divisor
}
switch
fs
.
Resource
{
case
"limits.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Limits
.
Cpu
(),
divisor
)
case
"limits.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Limits
.
Memory
(),
divisor
)
case
"requests.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Requests
.
Cpu
(),
divisor
)
case
"requests.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Requests
.
Memory
(),
divisor
)
}
return
""
,
fmt
.
Errorf
(
"unsupported container resource : %v"
,
fs
.
Resource
)
}
// convertResourceCPUToString converts cpu value to the format of divisor and returns
// ceiling of the value.
func
convertResourceCPUToString
(
cpu
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
c
:=
int64
(
math
.
Ceil
(
float64
(
cpu
.
MilliValue
())
/
float64
(
divisor
.
MilliValue
())))
return
strconv
.
FormatInt
(
c
,
10
),
nil
}
// convertResourceMemoryToString converts memory value to the format of divisor and returns
// ceiling of the value.
func
convertResourceMemoryToString
(
memory
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
m
:=
int64
(
math
.
Ceil
(
float64
(
memory
.
Value
())
/
float64
(
divisor
.
Value
())))
return
strconv
.
FormatInt
(
m
,
10
),
nil
}
pkg/api/resource_helpers_test.go
→
pkg/api/resource
/resource
_helpers_test.go
View file @
9837a985
...
...
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package
api
package
resource
import
(
"testing"
...
...
@@ -22,13 +22,14 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api"
)
func
TestResourceHelpers
(
t
*
testing
.
T
)
{
cpuLimit
:=
resource
.
MustParse
(
"10"
)
memoryLimit
:=
resource
.
MustParse
(
"10G"
)
resourceSpec
:=
ResourceRequirements
{
Limits
:
ResourceList
{
resourceSpec
:=
api
.
ResourceRequirements
{
Limits
:
api
.
ResourceList
{
"cpu"
:
cpuLimit
,
"memory"
:
memoryLimit
,
"kube.io/storage"
:
memoryLimit
,
...
...
@@ -40,8 +41,8 @@ func TestResourceHelpers(t *testing.T) {
if
res
:=
resourceSpec
.
Limits
.
Memory
();
res
.
Cmp
(
memoryLimit
)
!=
0
{
t
.
Errorf
(
"expected memorylimit %v, got %v"
,
memoryLimit
,
res
)
}
resourceSpec
=
ResourceRequirements
{
Limits
:
ResourceList
{
resourceSpec
=
api
.
ResourceRequirements
{
Limits
:
api
.
ResourceList
{
"memory"
:
memoryLimit
,
"kube.io/storage"
:
memoryLimit
,
},
...
...
@@ -55,7 +56,7 @@ func TestResourceHelpers(t *testing.T) {
}
func
TestDefaultResourceHelpers
(
t
*
testing
.
T
)
{
resourceList
:=
ResourceList
{}
resourceList
:=
api
.
ResourceList
{}
if
resourceList
.
Cpu
()
.
Format
!=
resource
.
DecimalSI
{
t
.
Errorf
(
"expected %v, actual %v"
,
resource
.
DecimalSI
,
resourceList
.
Cpu
()
.
Format
)
}
...
...
@@ -64,16 +65,16 @@ func TestDefaultResourceHelpers(t *testing.T) {
}
}
func
newPod
(
now
metav1
.
Time
,
ready
bool
,
beforeSec
int
)
*
Pod
{
conditionStatus
:=
ConditionFalse
func
newPod
(
now
metav1
.
Time
,
ready
bool
,
beforeSec
int
)
*
api
.
Pod
{
conditionStatus
:=
api
.
ConditionFalse
if
ready
{
conditionStatus
=
ConditionTrue
conditionStatus
=
api
.
ConditionTrue
}
return
&
Pod
{
Status
:
PodStatus
{
Conditions
:
[]
PodCondition
{
return
&
api
.
Pod
{
Status
:
api
.
PodStatus
{
Conditions
:
[]
api
.
PodCondition
{
{
Type
:
PodReady
,
Type
:
api
.
PodReady
,
LastTransitionTime
:
metav1
.
NewTime
(
now
.
Time
.
Add
(
-
1
*
time
.
Duration
(
beforeSec
)
*
time
.
Second
)),
Status
:
conditionStatus
,
},
...
...
@@ -81,40 +82,3 @@ func newPod(now metav1.Time, ready bool, beforeSec int) *Pod {
},
}
}
func
TestIsPodAvailable
(
t
*
testing
.
T
)
{
now
:=
metav1
.
Now
()
tests
:=
[]
struct
{
pod
*
Pod
minReadySeconds
int32
expected
bool
}{
{
pod
:
newPod
(
now
,
false
,
0
),
minReadySeconds
:
0
,
expected
:
false
,
},
{
pod
:
newPod
(
now
,
true
,
0
),
minReadySeconds
:
1
,
expected
:
false
,
},
{
pod
:
newPod
(
now
,
true
,
0
),
minReadySeconds
:
0
,
expected
:
true
,
},
{
pod
:
newPod
(
now
,
true
,
51
),
minReadySeconds
:
50
,
expected
:
true
,
},
}
for
i
,
test
:=
range
tests
{
isAvailable
:=
IsPodAvailable
(
test
.
pod
,
test
.
minReadySeconds
,
now
)
if
isAvailable
!=
test
.
expected
{
t
.
Errorf
(
"[tc #%d] expected available pod: %t, got: %t"
,
i
,
test
.
expected
,
isAvailable
)
}
}
}
pkg/api/resource_helpers.go
deleted
100644 → 0
View file @
d9920c53
/*
Copyright 2014 The Kubernetes 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
api
import
(
"fmt"
"math"
"strconv"
"time"
"k8s.io/apimachinery/pkg/api/resource"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Returns string version of ResourceName.
func
(
self
ResourceName
)
String
()
string
{
return
string
(
self
)
}
// Returns the CPU limit if specified.
func
(
self
*
ResourceList
)
Cpu
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceCPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
DecimalSI
}
}
// Returns the Memory limit if specified.
func
(
self
*
ResourceList
)
Memory
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceMemory
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
BinarySI
}
}
func
(
self
*
ResourceList
)
Pods
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourcePods
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
(
self
*
ResourceList
)
NvidiaGPU
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceNvidiaGPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
GetContainerStatus
(
statuses
[]
ContainerStatus
,
name
string
)
(
ContainerStatus
,
bool
)
{
for
i
:=
range
statuses
{
if
statuses
[
i
]
.
Name
==
name
{
return
statuses
[
i
],
true
}
}
return
ContainerStatus
{},
false
}
func
GetExistingContainerStatus
(
statuses
[]
ContainerStatus
,
name
string
)
ContainerStatus
{
for
i
:=
range
statuses
{
if
statuses
[
i
]
.
Name
==
name
{
return
statuses
[
i
]
}
}
return
ContainerStatus
{}
}
// IsPodAvailable returns true if a pod is available; false otherwise.
// Precondition for an available pod is that it must be ready. On top
// of that, there are two cases when a pod can be considered available:
// 1. minReadySeconds == 0, or
// 2. LastTransitionTime (is set) + minReadySeconds < current time
func
IsPodAvailable
(
pod
*
Pod
,
minReadySeconds
int32
,
now
metav1
.
Time
)
bool
{
if
!
IsPodReady
(
pod
)
{
return
false
}
c
:=
GetPodReadyCondition
(
pod
.
Status
)
minReadySecondsDuration
:=
time
.
Duration
(
minReadySeconds
)
*
time
.
Second
if
minReadySeconds
==
0
||
!
c
.
LastTransitionTime
.
IsZero
()
&&
c
.
LastTransitionTime
.
Add
(
minReadySecondsDuration
)
.
Before
(
now
.
Time
)
{
return
true
}
return
false
}
// IsPodReady returns true if a pod is ready; false otherwise.
func
IsPodReady
(
pod
*
Pod
)
bool
{
return
IsPodReadyConditionTrue
(
pod
.
Status
)
}
// IsPodReady retruns true if a pod is ready; false otherwise.
func
IsPodReadyConditionTrue
(
status
PodStatus
)
bool
{
condition
:=
GetPodReadyCondition
(
status
)
return
condition
!=
nil
&&
condition
.
Status
==
ConditionTrue
}
// Extracts the pod ready condition from the given status and returns that.
// Returns nil if the condition is not present.
func
GetPodReadyCondition
(
status
PodStatus
)
*
PodCondition
{
_
,
condition
:=
GetPodCondition
(
&
status
,
PodReady
)
return
condition
}
// GetPodCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func
GetPodCondition
(
status
*
PodStatus
,
conditionType
PodConditionType
)
(
int
,
*
PodCondition
)
{
if
status
==
nil
{
return
-
1
,
nil
}
for
i
:=
range
status
.
Conditions
{
if
status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
i
,
&
status
.
Conditions
[
i
]
}
}
return
-
1
,
nil
}
// GetNodeCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func
GetNodeCondition
(
status
*
NodeStatus
,
conditionType
NodeConditionType
)
(
int
,
*
NodeCondition
)
{
if
status
==
nil
{
return
-
1
,
nil
}
for
i
:=
range
status
.
Conditions
{
if
status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
i
,
&
status
.
Conditions
[
i
]
}
}
return
-
1
,
nil
}
// Updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if pod condition has changed or has been added.
func
UpdatePodCondition
(
status
*
PodStatus
,
condition
*
PodCondition
)
bool
{
condition
.
LastTransitionTime
=
metav1
.
Now
()
// Try to find this pod condition.
conditionIndex
,
oldCondition
:=
GetPodCondition
(
status
,
condition
.
Type
)
if
oldCondition
==
nil
{
// We are adding new pod condition.
status
.
Conditions
=
append
(
status
.
Conditions
,
*
condition
)
return
true
}
else
{
// We are updating an existing condition, so we need to check if it has changed.
if
condition
.
Status
==
oldCondition
.
Status
{
condition
.
LastTransitionTime
=
oldCondition
.
LastTransitionTime
}
isEqual
:=
condition
.
Status
==
oldCondition
.
Status
&&
condition
.
Reason
==
oldCondition
.
Reason
&&
condition
.
Message
==
oldCondition
.
Message
&&
condition
.
LastProbeTime
.
Equal
(
oldCondition
.
LastProbeTime
)
&&
condition
.
LastTransitionTime
.
Equal
(
oldCondition
.
LastTransitionTime
)
status
.
Conditions
[
conditionIndex
]
=
*
condition
// Return true if one of the fields have changed.
return
!
isEqual
}
}
// IsNodeReady returns true if a node is ready; false otherwise.
func
IsNodeReady
(
node
*
Node
)
bool
{
for
_
,
c
:=
range
node
.
Status
.
Conditions
{
if
c
.
Type
==
NodeReady
{
return
c
.
Status
==
ConditionTrue
}
}
return
false
}
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
// containers of the pod.
func
PodRequestsAndLimits
(
pod
*
Pod
)
(
reqs
map
[
ResourceName
]
resource
.
Quantity
,
limits
map
[
ResourceName
]
resource
.
Quantity
,
err
error
)
{
reqs
,
limits
=
map
[
ResourceName
]
resource
.
Quantity
{},
map
[
ResourceName
]
resource
.
Quantity
{}
for
_
,
container
:=
range
pod
.
Spec
.
Containers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
if
value
,
ok
:=
reqs
[
name
];
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
reqs
[
name
]
=
value
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
if
value
,
ok
:=
limits
[
name
];
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
limits
[
name
]
=
value
}
}
}
// init containers define the minimum of any resource
for
_
,
container
:=
range
pod
.
Spec
.
InitContainers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
value
,
ok
:=
reqs
[
name
]
if
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
value
,
ok
:=
limits
[
name
]
if
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
}
}
return
}
// ExtractContainerResourceValue extracts the value of a resource
// in an already known container
func
ExtractContainerResourceValue
(
fs
*
ResourceFieldSelector
,
container
*
Container
)
(
string
,
error
)
{
divisor
:=
resource
.
Quantity
{}
if
divisor
.
Cmp
(
fs
.
Divisor
)
==
0
{
divisor
=
resource
.
MustParse
(
"1"
)
}
else
{
divisor
=
fs
.
Divisor
}
switch
fs
.
Resource
{
case
"limits.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Limits
.
Cpu
(),
divisor
)
case
"limits.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Limits
.
Memory
(),
divisor
)
case
"requests.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Requests
.
Cpu
(),
divisor
)
case
"requests.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Requests
.
Memory
(),
divisor
)
}
return
""
,
fmt
.
Errorf
(
"unsupported container resource : %v"
,
fs
.
Resource
)
}
// convertResourceCPUToString converts cpu value to the format of divisor and returns
// ceiling of the value.
func
convertResourceCPUToString
(
cpu
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
c
:=
int64
(
math
.
Ceil
(
float64
(
cpu
.
MilliValue
())
/
float64
(
divisor
.
MilliValue
())))
return
strconv
.
FormatInt
(
c
,
10
),
nil
}
// convertResourceMemoryToString converts memory value to the format of divisor and returns
// ceiling of the value.
func
convertResourceMemoryToString
(
memory
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
m
:=
int64
(
math
.
Ceil
(
float64
(
memory
.
Value
())
/
float64
(
divisor
.
Value
())))
return
strconv
.
FormatInt
(
m
,
10
),
nil
}
pkg/client/unversioned/BUILD
View file @
9837a985
...
...
@@ -17,6 +17,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/pod:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/extensions:go_default_library",
...
...
pkg/client/unversioned/conditions.go
View file @
9837a985
...
...
@@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/extensions"
...
...
@@ -192,7 +193,7 @@ func PodRunningAndReady(event watch.Event) (bool, error) {
case
api
.
PodFailed
,
api
.
PodSucceeded
:
return
false
,
ErrPodCompleted
case
api
.
PodRunning
:
return
api
.
IsPodReady
(
t
),
nil
return
pod
.
IsPodReady
(
t
),
nil
}
}
return
false
,
nil
...
...
pkg/printers/internalversion/BUILD
View file @
9837a985
...
...
@@ -64,6 +64,7 @@ go_library(
"//pkg/api/events:go_default_library",
"//pkg/api/helper:go_default_library",
"//pkg/api/ref:go_default_library",
"//pkg/api/resource:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library",
...
...
pkg/printers/internalversion/describe.go
View file @
9837a985
...
...
@@ -49,6 +49,7 @@ import (
"k8s.io/kubernetes/pkg/api/events"
"k8s.io/kubernetes/pkg/api/helper"
"k8s.io/kubernetes/pkg/api/ref"
resourcehelper
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
...
...
@@ -1115,7 +1116,7 @@ func describeContainerEnvVars(container api.Container, resolverFn EnvVarResolver
}
w
.
Write
(
LEVEL_3
,
"%s:
\t
%s (%s:%s)
\n
"
,
e
.
Name
,
valueFrom
,
e
.
ValueFrom
.
FieldRef
.
APIVersion
,
e
.
ValueFrom
.
FieldRef
.
FieldPath
)
case
e
.
ValueFrom
.
ResourceFieldRef
!=
nil
:
valueFrom
,
err
:=
api
.
ExtractContainerResourceValue
(
e
.
ValueFrom
.
ResourceFieldRef
,
&
container
)
valueFrom
,
err
:=
resourcehelper
.
ExtractContainerResourceValue
(
e
.
ValueFrom
.
ResourceFieldRef
,
&
container
)
if
err
!=
nil
{
valueFrom
=
""
}
...
...
@@ -2337,7 +2338,7 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node
}
for
_
,
pod
:=
range
nodeNonTerminatedPodsList
.
Items
{
req
,
limit
,
err
:=
api
.
PodRequestsAndLimits
(
&
pod
)
req
,
limit
,
err
:=
resourcehelper
.
PodRequestsAndLimits
(
&
pod
)
if
err
!=
nil
{
return
err
}
...
...
@@ -2385,7 +2386,7 @@ func filterTerminatedPods(pods []*api.Pod) []*api.Pod {
func
getPodsTotalRequestsAndLimits
(
podList
*
api
.
PodList
)
(
reqs
map
[
api
.
ResourceName
]
resource
.
Quantity
,
limits
map
[
api
.
ResourceName
]
resource
.
Quantity
,
err
error
)
{
reqs
,
limits
=
map
[
api
.
ResourceName
]
resource
.
Quantity
{},
map
[
api
.
ResourceName
]
resource
.
Quantity
{}
for
_
,
pod
:=
range
podList
.
Items
{
podReqs
,
podLimits
,
err
:=
api
.
PodRequestsAndLimits
(
&
pod
)
podReqs
,
podLimits
,
err
:=
resourcehelper
.
PodRequestsAndLimits
(
&
pod
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
...
...
pkg/registry/core/pod/storage/BUILD
View file @
9837a985
...
...
@@ -43,6 +43,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/pod:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/policy/internalversion:go_default_library",
...
...
pkg/registry/core/pod/storage/storage.go
View file @
9837a985
...
...
@@ -31,6 +31,7 @@ import (
"k8s.io/apiserver/pkg/storage"
storeerr
"k8s.io/apiserver/pkg/storage/errors"
"k8s.io/kubernetes/pkg/api"
podutil
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/api/validation"
policyclient
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/policy/internalversion"
"k8s.io/kubernetes/pkg/kubelet/client"
...
...
@@ -165,7 +166,7 @@ func (r *BindingREST) setPodHostAndAnnotations(ctx genericapirequest.Context, po
for
k
,
v
:=
range
annotations
{
pod
.
Annotations
[
k
]
=
v
}
api
.
UpdatePodCondition
(
&
pod
.
Status
,
&
api
.
PodCondition
{
podutil
.
UpdatePodCondition
(
&
pod
.
Status
,
&
api
.
PodCondition
{
Type
:
api
.
PodScheduled
,
Status
:
api
.
ConditionTrue
,
})
...
...
staging/src/k8s.io/client-go/pkg/api/resource.go
0 → 100644
View file @
9837a985
/*
Copyright 2017 The Kubernetes 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
api
import
(
"k8s.io/apimachinery/pkg/api/resource"
)
func
(
self
ResourceName
)
String
()
string
{
return
string
(
self
)
}
// Returns the CPU limit if specified.
func
(
self
*
ResourceList
)
Cpu
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceCPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
DecimalSI
}
}
// Returns the Memory limit if specified.
func
(
self
*
ResourceList
)
Memory
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceMemory
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
BinarySI
}
}
func
(
self
*
ResourceList
)
Pods
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourcePods
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
(
self
*
ResourceList
)
NvidiaGPU
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceNvidiaGPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
staging/src/k8s.io/client-go/pkg/api/resource_helpers.go
deleted
100644 → 0
View file @
d9920c53
/*
Copyright 2014 The Kubernetes 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
api
import
(
"fmt"
"math"
"strconv"
"time"
"k8s.io/apimachinery/pkg/api/resource"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Returns string version of ResourceName.
func
(
self
ResourceName
)
String
()
string
{
return
string
(
self
)
}
// Returns the CPU limit if specified.
func
(
self
*
ResourceList
)
Cpu
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceCPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
DecimalSI
}
}
// Returns the Memory limit if specified.
func
(
self
*
ResourceList
)
Memory
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceMemory
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{
Format
:
resource
.
BinarySI
}
}
func
(
self
*
ResourceList
)
Pods
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourcePods
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
(
self
*
ResourceList
)
NvidiaGPU
()
*
resource
.
Quantity
{
if
val
,
ok
:=
(
*
self
)[
ResourceNvidiaGPU
];
ok
{
return
&
val
}
return
&
resource
.
Quantity
{}
}
func
GetContainerStatus
(
statuses
[]
ContainerStatus
,
name
string
)
(
ContainerStatus
,
bool
)
{
for
i
:=
range
statuses
{
if
statuses
[
i
]
.
Name
==
name
{
return
statuses
[
i
],
true
}
}
return
ContainerStatus
{},
false
}
func
GetExistingContainerStatus
(
statuses
[]
ContainerStatus
,
name
string
)
ContainerStatus
{
for
i
:=
range
statuses
{
if
statuses
[
i
]
.
Name
==
name
{
return
statuses
[
i
]
}
}
return
ContainerStatus
{}
}
// IsPodAvailable returns true if a pod is available; false otherwise.
// Precondition for an available pod is that it must be ready. On top
// of that, there are two cases when a pod can be considered available:
// 1. minReadySeconds == 0, or
// 2. LastTransitionTime (is set) + minReadySeconds < current time
func
IsPodAvailable
(
pod
*
Pod
,
minReadySeconds
int32
,
now
metav1
.
Time
)
bool
{
if
!
IsPodReady
(
pod
)
{
return
false
}
c
:=
GetPodReadyCondition
(
pod
.
Status
)
minReadySecondsDuration
:=
time
.
Duration
(
minReadySeconds
)
*
time
.
Second
if
minReadySeconds
==
0
||
!
c
.
LastTransitionTime
.
IsZero
()
&&
c
.
LastTransitionTime
.
Add
(
minReadySecondsDuration
)
.
Before
(
now
.
Time
)
{
return
true
}
return
false
}
// IsPodReady returns true if a pod is ready; false otherwise.
func
IsPodReady
(
pod
*
Pod
)
bool
{
return
IsPodReadyConditionTrue
(
pod
.
Status
)
}
// IsPodReady retruns true if a pod is ready; false otherwise.
func
IsPodReadyConditionTrue
(
status
PodStatus
)
bool
{
condition
:=
GetPodReadyCondition
(
status
)
return
condition
!=
nil
&&
condition
.
Status
==
ConditionTrue
}
// Extracts the pod ready condition from the given status and returns that.
// Returns nil if the condition is not present.
func
GetPodReadyCondition
(
status
PodStatus
)
*
PodCondition
{
_
,
condition
:=
GetPodCondition
(
&
status
,
PodReady
)
return
condition
}
// GetPodCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func
GetPodCondition
(
status
*
PodStatus
,
conditionType
PodConditionType
)
(
int
,
*
PodCondition
)
{
if
status
==
nil
{
return
-
1
,
nil
}
for
i
:=
range
status
.
Conditions
{
if
status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
i
,
&
status
.
Conditions
[
i
]
}
}
return
-
1
,
nil
}
// GetNodeCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func
GetNodeCondition
(
status
*
NodeStatus
,
conditionType
NodeConditionType
)
(
int
,
*
NodeCondition
)
{
if
status
==
nil
{
return
-
1
,
nil
}
for
i
:=
range
status
.
Conditions
{
if
status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
i
,
&
status
.
Conditions
[
i
]
}
}
return
-
1
,
nil
}
// Updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if pod condition has changed or has been added.
func
UpdatePodCondition
(
status
*
PodStatus
,
condition
*
PodCondition
)
bool
{
condition
.
LastTransitionTime
=
metav1
.
Now
()
// Try to find this pod condition.
conditionIndex
,
oldCondition
:=
GetPodCondition
(
status
,
condition
.
Type
)
if
oldCondition
==
nil
{
// We are adding new pod condition.
status
.
Conditions
=
append
(
status
.
Conditions
,
*
condition
)
return
true
}
else
{
// We are updating an existing condition, so we need to check if it has changed.
if
condition
.
Status
==
oldCondition
.
Status
{
condition
.
LastTransitionTime
=
oldCondition
.
LastTransitionTime
}
isEqual
:=
condition
.
Status
==
oldCondition
.
Status
&&
condition
.
Reason
==
oldCondition
.
Reason
&&
condition
.
Message
==
oldCondition
.
Message
&&
condition
.
LastProbeTime
.
Equal
(
oldCondition
.
LastProbeTime
)
&&
condition
.
LastTransitionTime
.
Equal
(
oldCondition
.
LastTransitionTime
)
status
.
Conditions
[
conditionIndex
]
=
*
condition
// Return true if one of the fields have changed.
return
!
isEqual
}
}
// IsNodeReady returns true if a node is ready; false otherwise.
func
IsNodeReady
(
node
*
Node
)
bool
{
for
_
,
c
:=
range
node
.
Status
.
Conditions
{
if
c
.
Type
==
NodeReady
{
return
c
.
Status
==
ConditionTrue
}
}
return
false
}
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
// containers of the pod.
func
PodRequestsAndLimits
(
pod
*
Pod
)
(
reqs
map
[
ResourceName
]
resource
.
Quantity
,
limits
map
[
ResourceName
]
resource
.
Quantity
,
err
error
)
{
reqs
,
limits
=
map
[
ResourceName
]
resource
.
Quantity
{},
map
[
ResourceName
]
resource
.
Quantity
{}
for
_
,
container
:=
range
pod
.
Spec
.
Containers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
if
value
,
ok
:=
reqs
[
name
];
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
reqs
[
name
]
=
value
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
if
value
,
ok
:=
limits
[
name
];
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
else
{
value
.
Add
(
quantity
)
limits
[
name
]
=
value
}
}
}
// init containers define the minimum of any resource
for
_
,
container
:=
range
pod
.
Spec
.
InitContainers
{
for
name
,
quantity
:=
range
container
.
Resources
.
Requests
{
value
,
ok
:=
reqs
[
name
]
if
!
ok
{
reqs
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
reqs
[
name
]
=
*
quantity
.
Copy
()
}
}
for
name
,
quantity
:=
range
container
.
Resources
.
Limits
{
value
,
ok
:=
limits
[
name
]
if
!
ok
{
limits
[
name
]
=
*
quantity
.
Copy
()
continue
}
if
quantity
.
Cmp
(
value
)
>
0
{
limits
[
name
]
=
*
quantity
.
Copy
()
}
}
}
return
}
// ExtractContainerResourceValue extracts the value of a resource
// in an already known container
func
ExtractContainerResourceValue
(
fs
*
ResourceFieldSelector
,
container
*
Container
)
(
string
,
error
)
{
divisor
:=
resource
.
Quantity
{}
if
divisor
.
Cmp
(
fs
.
Divisor
)
==
0
{
divisor
=
resource
.
MustParse
(
"1"
)
}
else
{
divisor
=
fs
.
Divisor
}
switch
fs
.
Resource
{
case
"limits.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Limits
.
Cpu
(),
divisor
)
case
"limits.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Limits
.
Memory
(),
divisor
)
case
"requests.cpu"
:
return
convertResourceCPUToString
(
container
.
Resources
.
Requests
.
Cpu
(),
divisor
)
case
"requests.memory"
:
return
convertResourceMemoryToString
(
container
.
Resources
.
Requests
.
Memory
(),
divisor
)
}
return
""
,
fmt
.
Errorf
(
"unsupported container resource : %v"
,
fs
.
Resource
)
}
// convertResourceCPUToString converts cpu value to the format of divisor and returns
// ceiling of the value.
func
convertResourceCPUToString
(
cpu
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
c
:=
int64
(
math
.
Ceil
(
float64
(
cpu
.
MilliValue
())
/
float64
(
divisor
.
MilliValue
())))
return
strconv
.
FormatInt
(
c
,
10
),
nil
}
// convertResourceMemoryToString converts memory value to the format of divisor and returns
// ceiling of the value.
func
convertResourceMemoryToString
(
memory
*
resource
.
Quantity
,
divisor
resource
.
Quantity
)
(
string
,
error
)
{
m
:=
int64
(
math
.
Ceil
(
float64
(
memory
.
Value
())
/
float64
(
divisor
.
Value
())))
return
strconv
.
FormatInt
(
m
,
10
),
nil
}
vendor/BUILD
View file @
9837a985
...
...
@@ -13905,7 +13905,7 @@ go_library(
"k8s.io/client-go/pkg/api/json.go",
"k8s.io/client-go/pkg/api/objectreference.go",
"k8s.io/client-go/pkg/api/register.go",
"k8s.io/client-go/pkg/api/resource
_helpers
.go",
"k8s.io/client-go/pkg/api/resource.go",
"k8s.io/client-go/pkg/api/taint.go",
"k8s.io/client-go/pkg/api/toleration.go",
"k8s.io/client-go/pkg/api/types.go",
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment