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
d5ffc4b1
Unverified
Commit
d5ffc4b1
authored
Nov 01, 2022
by
ShylajaDevadiga
Committed by
GitHub
Nov 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add snapshot restore e2e test (#6396)
* Add snapshot and restore test Signed-off-by:
Shylaja Devadiga
<
shylaja@rancher.com
>
parent
3aae7b87
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
314 additions
and
0 deletions
+314
-0
Vagrantfile
tests/e2e/snapshotrestore/Vagrantfile
+125
-0
snapshotrestore_test.go
tests/e2e/snapshotrestore/snapshotrestore_test.go
+189
-0
No files found.
tests/e2e/snapshotrestore/Vagrantfile
0 → 100644
View file @
d5ffc4b1
ENV
[
'VAGRANT_NO_PARALLEL'
]
=
'no'
NODE_ROLES
=
(
ENV
[
'E2E_NODE_ROLES'
]
||
[
"server-0"
,
"server-1"
,
"server-2"
,
"agent-0"
,
"agent-1"
])
NODE_BOXES
=
(
ENV
[
'E2E_NODE_BOXES'
]
||
[
'generic/ubuntu2004'
,
'generic/ubuntu2004'
,
'generic/ubuntu2004'
,
'generic/ubuntu2004'
,
'generic/ubuntu2004'
])
GITHUB_BRANCH
=
(
ENV
[
'E2E_GITHUB_BRANCH'
]
||
"master"
)
RELEASE_VERSION
=
(
ENV
[
'E2E_RELEASE_VERSION'
]
||
""
)
EXTERNAL_DB
=
(
ENV
[
'E2E_EXTERNAL_DB'
]
||
"etcd"
)
NODE_CPUS
=
(
ENV
[
'E2E_NODE_CPUS'
]
||
2
).
to_i
NODE_MEMORY
=
(
ENV
[
'E2E_NODE_MEMORY'
]
||
1024
).
to_i
# Virtualbox >= 6.1.28 require `/etc/vbox/network.conf` for expanded private networks
NETWORK_PREFIX
=
"10.10.10"
install_type
=
""
def
provision
(
vm
,
role
,
role_num
,
node_num
)
vm
.
box
=
NODE_BOXES
[
node_num
]
vm
.
hostname
=
role
# An expanded netmask is required to allow VM<-->VM communication, virtualbox defaults to /32
node_ip
=
"
#{
NETWORK_PREFIX
}
.
#{
100
+
node_num
}
"
vm
.
network
"private_network"
,
ip:
node_ip
,
netmask:
"255.255.255.0"
scripts_location
=
Dir
.
exists?
(
"./scripts"
)
?
"./scripts"
:
"../scripts"
vagrant_defaults
=
File
.
exists?
(
"./vagrantdefaults.rb"
)
?
"./vagrantdefaults.rb"
:
"../vagrantdefaults.rb"
load
vagrant_defaults
defaultOSConfigure
(
vm
)
install_type
=
getInstallType
(
vm
,
RELEASE_VERSION
,
GITHUB_BRANCH
)
vm
.
provision
"shell"
,
inline:
"ping -c 2 k3s.io"
db_type
=
getDBType
(
role
,
role_num
,
vm
)
if
role
.
include?
(
"server"
)
&&
role_num
==
0
vm
.
provision
'k3s-primary-server'
,
type:
'k3s'
,
run:
'once'
do
|
k3s
|
k3s
.
args
=
"server "
k3s
.
config
=
<<~
YAML
token: vagrant
node-external-ip:
#{
NETWORK_PREFIX
}
.100
flannel-iface: eth1
tls-san:
#{
NETWORK_PREFIX
}
.100.nip.io
#{
db_type
}
YAML
k3s
.
env
=
%W[K3S_KUBECONFIG_MODE=0644
#{
install_type
}
]
k3s
.
config_mode
=
'0644'
# side-step https://github.com/k3s-io/k3s/issues/4321
end
elsif
role
.
include?
(
"server"
)
&&
role_num
!=
0
vm
.
provision
'k3s-secondary-server'
,
type:
'k3s'
,
run:
'once'
do
|
k3s
|
k3s
.
args
=
"server"
k3s
.
config
=
<<~
YAML
server: "https://
#{
NETWORK_PREFIX
}
.100:6443"
token: vagrant
node-external-ip:
#{
node_ip
}
flannel-iface: eth1
#{
db_type
}
YAML
k3s
.
env
=
%W[K3S_KUBECONFIG_MODE=0644 K3S_TOKEN=vagrant
#{
install_type
}
]
k3s
.
config_mode
=
'0644'
# side-step https://github.com/k3s-io/k3s/issues/4321
end
end
if
role
.
include?
(
"agent"
)
vm
.
provision
'k3s-agent'
,
type:
'k3s'
,
run:
'once'
do
|
k3s
|
k3s
.
args
=
"agent"
k3s
.
config
=
<<~
YAML
server: "https://
#{
NETWORK_PREFIX
}
.100:6443"
token: vagrant
node-external-ip:
#{
node_ip
}
flannel-iface: eth1
#{
db_type
}
YAML
k3s
.
env
=
%W[K3S_KUBECONFIG_MODE=0644
#{
install_type
}
]
k3s
.
config_mode
=
'0644'
# side-step https://github.com/k3s-io/k3s/issues/4321
end
end
if
vm
.
box
.
to_s
.
include?
(
"microos"
)
vm
.
provision
'k3s-reload'
,
type:
'reload'
,
run:
'once'
if
!
EXTERNAL_DB
.
empty?
vm
.
provision
"shell"
,
inline:
"docker start
#{
EXTERNAL_DB
}
"
end
end
# This step does not run by default and is designed to be called by higher level tools
end
def
getDBType
(
role
,
role_num
,
vm
)
if
(
EXTERNAL_DB
==
""
||
EXTERNAL_DB
==
"etcd"
)
if
role
.
include?
(
"server"
)
&&
role_num
==
0
return
"cluster-init: true"
end
else
puts
"Unknown EXTERNAL_DB: "
+
EXTERNAL_DB
abort
end
return
""
end
Vagrant
.
configure
(
"2"
)
do
|
config
|
config
.
vagrant
.
plugins
=
[
"vagrant-k3s"
,
"vagrant-reload"
]
# Default provider is libvirt, virtualbox is only provided as a backup
config
.
vm
.
provider
"libvirt"
do
|
v
|
v
.
cpus
=
NODE_CPUS
v
.
memory
=
NODE_MEMORY
end
config
.
vm
.
provider
"virtualbox"
do
|
v
|
v
.
cpus
=
NODE_CPUS
v
.
memory
=
NODE_MEMORY
end
if
NODE_ROLES
.
kind_of?
(
String
)
NODE_ROLES
=
NODE_ROLES
.
split
(
" "
,
-
1
)
end
if
NODE_BOXES
.
kind_of?
(
String
)
NODE_BOXES
=
NODE_BOXES
.
split
(
" "
,
-
1
)
end
# Must iterate on the index, vagrant does not understand iterating
# over the node roles themselves
NODE_ROLES
.
length
.
times
do
|
i
|
name
=
NODE_ROLES
[
i
]
role_num
=
name
.
split
(
"-"
,
-
1
).
pop
.
to_i
config
.
vm
.
define
name
do
|
node
|
provision
(
node
.
vm
,
name
,
role_num
,
i
)
end
end
end
tests/e2e/snapshotrestore/snapshotrestore_test.go
0 → 100644
View file @
d5ffc4b1
package
snapshotrestore
import
(
"flag"
"fmt"
"os"
"strings"
"testing"
"github.com/k3s-io/k3s/tests/e2e"
.
"github.com/onsi/ginkgo/v2"
.
"github.com/onsi/gomega"
)
// Valid nodeOS:
// generic/ubuntu2004, generic/centos7, generic/rocky8,
// opensuse/Leap-15.3.x86_64, dweomer/microos.amd64
var
nodeOS
=
flag
.
String
(
"nodeOS"
,
"generic/ubuntu2004"
,
"VM operating system"
)
var
serverCount
=
flag
.
Int
(
"serverCount"
,
3
,
"number of server nodes"
)
var
agentCount
=
flag
.
Int
(
"agentCount"
,
1
,
"number of agent nodes"
)
var
hardened
=
flag
.
Bool
(
"hardened"
,
false
,
"true or false"
)
var
ci
=
flag
.
Bool
(
"ci"
,
false
,
"running on CI"
)
var
local
=
flag
.
Bool
(
"local"
,
false
,
"deploy a locally built K3s binary"
)
// Environment Variables Info:
// E2E_EXTERNAL_DB: mysql, postgres, etcd (default: etcd)
// E2E_RELEASE_VERSION=v1.23.1+k3s2 (default: latest commit from master)
func
Test_E2ESnapshotRestore
(
t
*
testing
.
T
)
{
RegisterFailHandler
(
Fail
)
flag
.
Parse
()
RunSpecs
(
t
,
"SnapshotRestore Test Suite"
)
}
var
(
kubeConfigFile
string
serverNodeNames
[]
string
agentNodeNames
[]
string
snapshotname
string
)
var
_
=
Describe
(
"Verify Create"
,
Ordered
,
func
()
{
Context
(
"Cluster :"
,
func
()
{
It
(
"Starts up with no issues"
,
func
()
{
var
err
error
if
*
local
{
serverNodeNames
,
agentNodeNames
,
err
=
e2e
.
CreateLocalCluster
(
*
nodeOS
,
*
serverCount
,
*
agentCount
)
}
else
{
serverNodeNames
,
agentNodeNames
,
err
=
e2e
.
CreateCluster
(
*
nodeOS
,
*
serverCount
,
*
agentCount
)
}
Expect
(
err
)
.
NotTo
(
HaveOccurred
(),
e2e
.
GetVagrantLog
(
err
))
fmt
.
Println
(
"CLUSTER CONFIG"
)
fmt
.
Println
(
"OS:"
,
*
nodeOS
)
fmt
.
Println
(
"Server Nodes:"
,
serverNodeNames
)
fmt
.
Println
(
"Agent Nodes:"
,
agentNodeNames
)
kubeConfigFile
,
err
=
e2e
.
GenKubeConfigFile
(
serverNodeNames
[
0
])
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
})
It
(
"Checks Node and Pod Status"
,
func
()
{
fmt
.
Printf
(
"
\n
Fetching node status
\n
"
)
Eventually
(
func
(
g
Gomega
)
{
nodes
,
err
:=
e2e
.
ParseNodes
(
kubeConfigFile
,
false
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
for
_
,
node
:=
range
nodes
{
g
.
Expect
(
node
.
Status
)
.
Should
(
Equal
(
"Ready"
))
}
},
"420s"
,
"5s"
)
.
Should
(
Succeed
())
_
,
_
=
e2e
.
ParseNodes
(
kubeConfigFile
,
true
)
fmt
.
Printf
(
"
\n
Fetching Pods status
\n
"
)
Eventually
(
func
(
g
Gomega
)
{
pods
,
err
:=
e2e
.
ParsePods
(
kubeConfigFile
,
false
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
for
_
,
pod
:=
range
pods
{
if
strings
.
Contains
(
pod
.
Name
,
"helm-install"
)
{
g
.
Expect
(
pod
.
Status
)
.
Should
(
Equal
(
"Completed"
),
pod
.
Name
)
}
else
{
g
.
Expect
(
pod
.
Status
)
.
Should
(
Equal
(
"Running"
),
pod
.
Name
)
}
}
},
"620s"
,
"5s"
)
.
Should
(
Succeed
())
_
,
_
=
e2e
.
ParsePods
(
kubeConfigFile
,
true
)
})
It
(
"Verifies test workload before snapshot is created"
,
func
()
{
res
,
err
:=
e2e
.
DeployWorkload
(
"clusterip.yaml"
,
kubeConfigFile
,
*
hardened
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
(),
"Cluster IP manifest not deployed: "
+
res
)
Eventually
(
func
(
g
Gomega
)
{
cmd
:=
"kubectl get pods -o=name -l k8s-app=nginx-app-clusterip --field-selector=status.phase=Running --kubeconfig="
+
kubeConfigFile
res
,
err
:=
e2e
.
RunCommand
(
cmd
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
g
.
Expect
(
res
)
.
Should
((
ContainSubstring
(
"test-clusterip"
)),
"failed cmd: "
+
cmd
+
" result: "
+
res
)
},
"240s"
,
"5s"
)
.
Should
(
Succeed
())
})
It
(
"Verifies Snapshot is created"
,
func
()
{
Eventually
(
func
(
g
Gomega
)
{
cmd
:=
"sudo k3s etcd-snapshot"
_
,
err
:=
e2e
.
RunCmdOnNode
(
cmd
,
"server-0"
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
cmd
=
"sudo ls /var/lib/rancher/k3s/server/db/snapshots/"
snapshotname
,
err
=
e2e
.
RunCmdOnNode
(
cmd
,
"server-0"
)
fmt
.
Println
(
"Snapshot Name"
,
snapshotname
)
g
.
Expect
(
snapshotname
)
.
Should
(
ContainSubstring
(
"on-demand-server-0"
))
},
"420s"
,
"10s"
)
.
Should
(
Succeed
())
})
It
(
"Verifies another test workload after snapshot is created"
,
func
()
{
_
,
err
:=
e2e
.
DeployWorkload
(
"nodeport.yaml"
,
kubeConfigFile
,
*
hardened
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
(),
"NodePort manifest not deployed"
)
Eventually
(
func
(
g
Gomega
)
{
cmd
:=
"kubectl get pods -o=name -l k8s-app=nginx-app-nodeport --field-selector=status.phase=Running --kubeconfig="
+
kubeConfigFile
res
,
err
:=
e2e
.
RunCommand
(
cmd
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
g
.
Expect
(
res
)
.
Should
(
ContainSubstring
(
"test-nodeport"
),
"nodeport pod was not created"
)
},
"240s"
,
"5s"
)
.
Should
(
Succeed
())
})
It
(
"Verifies snapshot is restored successfully and validates only test workload1 is present"
,
func
()
{
//Stop k3s on all nodes
for
_
,
nodeName
:=
range
serverNodeNames
{
cmd
:=
"sudo systemctl stop k3s"
_
,
err
:=
e2e
.
RunCmdOnNode
(
cmd
,
nodeName
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
}
//Restores from snapshot on server-0
for
_
,
nodeName
:=
range
serverNodeNames
{
if
nodeName
==
"server-0"
{
cmd
:=
"sudo k3s server --cluster-init --cluster-reset --cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/"
+
snapshotname
res
,
err
:=
e2e
.
RunCmdOnNode
(
cmd
,
nodeName
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
res
)
.
Should
(
ContainSubstring
(
"Managed etcd cluster membership has been reset, restart without --cluster-reset flag now"
))
cmd
=
"sudo systemctl start k3s"
_
,
err
=
e2e
.
RunCmdOnNode
(
cmd
,
nodeName
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
}
}
//Verifies node is up and pods running
fmt
.
Printf
(
"
\n
Fetching node status
\n
"
)
Eventually
(
func
(
g
Gomega
)
{
nodes
,
err
:=
e2e
.
ParseNodes
(
kubeConfigFile
,
false
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
for
_
,
node
:=
range
nodes
{
g
.
Expect
(
node
.
Status
)
.
Should
(
Equal
(
"Ready"
))
}
},
"420s"
,
"5s"
)
.
Should
(
Succeed
())
_
,
_
=
e2e
.
ParseNodes
(
kubeConfigFile
,
true
)
fmt
.
Printf
(
"
\n
Fetching Pods status
\n
"
)
Eventually
(
func
(
g
Gomega
)
{
pods
,
err
:=
e2e
.
ParsePods
(
kubeConfigFile
,
false
)
g
.
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
for
_
,
pod
:=
range
pods
{
if
strings
.
Contains
(
pod
.
Name
,
"helm-install"
)
{
g
.
Expect
(
pod
.
Status
)
.
Should
(
Equal
(
"Completed"
),
pod
.
Name
)
}
else
{
g
.
Expect
(
pod
.
Status
)
.
Should
(
Equal
(
"Running"
),
pod
.
Name
)
}
}
},
"620s"
,
"5s"
)
.
Should
(
Succeed
())
_
,
_
=
e2e
.
ParsePods
(
kubeConfigFile
,
true
)
//Verifies test workload1 is present
//Verifies test workload2 is not present
cmd
:=
"kubectl get pods --kubeconfig="
+
kubeConfigFile
res
,
err
:=
e2e
.
RunCommand
(
cmd
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
res
)
.
Should
(
ContainSubstring
(
"test-clusterip"
))
Expect
(
res
)
.
ShouldNot
(
ContainSubstring
(
"test-nodeport"
))
})
})
})
var
failed
bool
var
_
=
AfterEach
(
func
()
{
failed
=
failed
||
CurrentSpecReport
()
.
Failed
()
})
var
_
=
AfterSuite
(
func
()
{
if
failed
&&
!*
ci
{
fmt
.
Println
(
"FAILED!"
)
}
else
{
Expect
(
e2e
.
DestroyCluster
())
.
To
(
Succeed
())
Expect
(
os
.
Remove
(
kubeConfigFile
))
.
To
(
Succeed
())
}
})
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