Skip to content

Commit

Permalink
Providing startTime and currentTime to facilitate timeout in case of …
Browse files Browse the repository at this point in the history
…ytt wait rules (carvel-dev#1023)

* Providing startTime and currentTime to facilitate timeout in case of ytt wait rules

Signed-off-by: Rohit Aggarwal <[email protected]>

* Update test/e2e/custom_wait_rules_test.go

Co-authored-by: Praveen Rewar <[email protected]>

---------

Signed-off-by: Rohit Aggarwal <[email protected]>
Co-authored-by: Rohit Aggarwal <[email protected]>
Co-authored-by: Praveen Rewar <[email protected]>
  • Loading branch information
3 people authored Sep 27, 2024
1 parent b7ceac1 commit 2e0c8d2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
9 changes: 8 additions & 1 deletion pkg/kapp/resourcesmisc/custom_waiting_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,17 @@ func (s CustomWaitingResource) IsDoneApplying() DoneApplyState {
}

if s.waitRule.Ytt != nil {
startTime, found := timeoutMap.Load(s.resource.Description())
if !found {
startTime = time.Now().Unix()
timeoutMap.Store(s.resource.Description(), startTime)
}
configObj, err := WaitRuleContractV1{
ResourceMatcher: ctlres.AnyMatcher{
Matchers: ctlconf.ResourceMatchers(s.waitRule.ResourceMatchers).AsResourceMatchers()},
Starlark: s.waitRule.Ytt.FuncContractV1.Resource,
Starlark: s.waitRule.Ytt.FuncContractV1.Resource,
CurrentTime: time.Now().Unix(),
StartTime: startTime.(int64),
}.Apply(s.resource)
if err != nil {
return DoneApplyState{Done: true, Successful: false, Message: fmt.Sprintf(
Expand Down
3 changes: 3 additions & 0 deletions pkg/kapp/resourcesmisc/wait_rule_contract_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
type WaitRuleContractV1 struct {
ResourceMatcher ctlres.ResourceMatcher
Starlark string
CurrentTime int64
StartTime int64
}

type waitRuleContractV1Result struct {
Expand Down Expand Up @@ -48,6 +50,7 @@ func (t WaitRuleContractV1) evalYtt(res ctlres.Resource) (*WaitRuleContractV1Res
}
return yaml.Marshal(res.DeepCopyRaw())
}
opts.DataValuesFlags.KVsFromStrings = []string{fmt.Sprintf("startTime=%d", t.StartTime), fmt.Sprintf("currentTime=%d", t.CurrentTime)}

filesToProcess := []*files.File{
files.MustNewFileFromSource(files.NewBytesSource("resource.star", []byte(t.Starlark))),
Expand Down
62 changes: 62 additions & 0 deletions test/e2e/custom_wait_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,65 @@ Succeeded`))
require.Equal(t, expectedOutput, out)
})
}

func TestYTTWaitRuleWithTimeout(t *testing.T) {
env := BuildEnv(t)
logger := Logger{}
kapp := Kapp{t, env.Namespace, env.KappBinaryPath, logger}
name := "test-custom-wait-rule-timeout-contract-v1"

yaml := `
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: %s
ports:
- containerPort: 80
---
apiVersion: kapp.k14s.io/v1alpha1
kind: Config
waitRules:
- ytt:
funcContractV1:
resource.star: |
def is_done(resource):
for condition in resource.status.conditions:
if condition.type == "ContainersReady" and condition.status == "False":
expiryTime = getExpiryTime(resource.startTime)
if int(resource.currentTime) - expiryTime > 0:
return {"done": True, "successful": False, "message": "Continuously failed for 50s with " + condition.message}
else:
return {"done": False, "successful": False, "message": condition.message}
end
elif condition.type == "Ready" and condition.status == "True":
return {"done": True, "successful": True, "message": condition.message}
end
end
return {"done": False, "successful": False, "message": "Not in Failed or Running state"}
end
def getExpiryTime(startTime):
return int(startTime)+50
end
resourceMatchers:
- apiVersionKindMatcher: {apiVersion: v1, kind: Pod}
`

cleanUp := func() {
kapp.Run([]string{"delete", "-a", name})
}
cleanUp()
defer cleanUp()

logger.Section("Deploy timeout after staying in a condition for certain time with ytt wait rules", func() {
_, err := kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", name, "--json"},
RunOpts{IntoNs: true, AllowError: true, StdinReader: strings.NewReader(fmt.Sprintf(yaml, "nginx:200"))})

require.Error(t, err)
require.Contains(t, err.Error(), "Continuously failed for 50s with")
})
}

0 comments on commit 2e0c8d2

Please sign in to comment.