Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OADP-2982: Add a sample / example of a VM backup and restore that works with default openshift-virtualization #1363

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 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
41 changes: 41 additions & 0 deletions tests/e2e/sample-applications/virt-todo/README.MD
weshayutin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# notes:
Obviously there are improvements to this workflow, however this is meant to
serve as a template or example to fit into other working test frameworks.

# To install
setup the openshift-virtualization operator

# Start vm
`oc create -f namemspace-virttodo.yaml -f virtualmachine-fedora-close-carp.yaml -f service.yaml -f vmroute.yaml`
weshayutin marked this conversation as resolved.
Show resolved Hide resolved

# Check volumeMode
`oc get pvc fedora-close-carp -o yaml -n virttodo | grep volumeMode`

# Wait for the cloud-init scripts to:
* install mariadb
* install and start the todolist app

* login w/ test/dog8code
`tail -f /var/log/cloud-init-output.log`

# Add data to the todolist
* get the route
* `oc get route -n virttodo`
* open browser to $route
* add data

# Build out the test.py
* edit the test.py script, add the route prepended with http://
weshayutin marked this conversation as resolved.
Show resolved Hide resolved
`python test.py`

# Backup vm
`oc create -f backup_virttodo.yaml`

# Delete everything
`oc delete -f namemspace-virttodo.yaml -f virtualmachine-fedora-close-carp.yaml -f service.yaml -f vmroute.yaml`

# Restore vm
`oc create -f restore_virttodo.yaml`

# Check the data
* compare the data you entered prior to the backup with the current data
12 changes: 12 additions & 0 deletions tests/e2e/sample-applications/virt-todo/backup_virttodo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: velero.io/v1
kind: Backup
metadata:
name: virttodo-backup-dm-1
namespace: openshift-adp
spec:
includedNamespaces:
- virttodo
storageLocation: default
ttl: 720h0m0s
snapshotMoveData: True
defaultVolumesToFsBackup: False
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: virttodo
8 changes: 8 additions & 0 deletions tests/e2e/sample-applications/virt-todo/restore_virttodo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: velero.io/v1
kind: Restore
metadata:
name: virttodo-restore-1
namespace: openshift-adp
spec:
backupName: virttodo-backup-dm-1
restorePVs: true
13 changes: 13 additions & 0 deletions tests/e2e/sample-applications/virt-todo/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: vm-service
namespace: virttodo
spec:
selector:
special: key
ports:
- name: todoport
port: 8000
targetPort: 8000
type: NodePort
179 changes: 179 additions & 0 deletions tests/e2e/sample-applications/virt-todo/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#!/usr/bin/env python
weshayutin marked this conversation as resolved.
Show resolved Hide resolved
from datetime import datetime
import json
import requests


#base_url = "http://localhost:8000"
weshayutin marked this conversation as resolved.
Show resolved Hide resolved
base_url = "http://vmroute-virttodo.apps.cluster-wdh03122024metala.wdh03122024metala.mg.dog8code.com"
# example remote
# base_url = "http://todolist-route-mysql-persistent.apps.cluster-wdh01102024g.wdh01102024g.mg.dog8code.com"
weshayutin marked this conversation as resolved.
Show resolved Hide resolved

def updateToDo(id, completed):
"""Update data to the todo application

Args:
item_dict: dict of todo item
completed: bool

Returns:
weshayutin marked this conversation as resolved.
Show resolved Hide resolved
{"updated": true/false}
"""
data = {
"id": id,
"completed": completed
}

# Set the endpoint URL
endpoint = base_url + "/todo/" + str(id)
# Send a POST request with the data and the endpoint URL
response = requests.post(endpoint, data=data)
# Check the status code of the response
if response.status_code == 201 or response.status_code == 200:
print("Task updated successfully!")
return True
else:
print("Error updating task.")
return False


def createToDo(description, completed):
"""Post data to the todo application

Args:
description: todo list description
completed: bool

Returns:
id of todo item in db
"""
data = {
"description": description,
"completed": completed
}

# Set the endpoint URL
endpoint = base_url + "/todo"
# Send a POST request with the data and the endpoint URL
response = requests.post(endpoint, data=data)
# Check the status code of the response
if response.status_code == 201 or response.status_code == 200:
print("Task created successfully!")
else:
print("Error creating task.")
response_dict = json.loads(response.text)[0]
return response_dict

def checkToDoLists(completed):
"""Post data to the todo application
weshayutin marked this conversation as resolved.
Show resolved Hide resolved

Args:
completed: bool

Returns:
json list
"""
# Set the endpoint URL
if completed:
endpoint = base_url + "/todo-completed"
else:
endpoint = base_url + "/todo-incomplete"
# Send a POST request with the data and the endpoint URL
response = requests.get(endpoint)
# Check the status code of the response
if response.status_code == 201 or response.status_code == 200:
print("Got list of items")
else:
print("Failed to get list of items")
response_dict = json.loads(response.text)
return response_dict

def deleteToDoItems(item):
"""Post data to the todo application
weshayutin marked this conversation as resolved.
Show resolved Hide resolved

Args:
item: dict

Returns:
bool
"""

endpoint = base_url + "/todo/" + str(item["Id"])
# Send a POST request with the data and the endpoint URL
response = requests.delete(endpoint)
# Check the status code of the response
if response.status_code == 201 or response.status_code == 200:
print("Deleted item " + str(item["Id"]))
return True
else:
print("Failed to delete item " + str(item["Id"]))
return False



def main():
date = datetime.today().strftime('%Y-%m-%d-%H:%M:%S')
# create todo items
test1 = createToDo("pytest-1-" + date, False)
test2 = createToDo("pytest-2-" + date, False)
test3 = createToDo("pytest-1-" + date, False)

# update todo items
success = updateToDo(test1["Id"], True)
success = updateToDo(test2["Id"], True)

# check todo's
completed = checkToDoLists(True)
incomplete = checkToDoLists(False)
print("COMPLETED ITEMS:")
print(completed)
print("INCOMPLETE ITEMS:")
print(incomplete)

# test complete or incomplete
found_completed = False
for i in completed:
if test1["Description"] == i["Description"]:
found_completed = True

found_incomplete = False
for i in incomplete:
if test3["Description"] == i["Description"]:
found_incomplete = True

if found_completed == False or found_incomplete == False:
print("FAILED complete / incomplete TEST")
else:
print("SUCCESS!")

# Delete items
deleteToDoItems(test1)
deleteToDoItems(test3)
completed = checkToDoLists(True)
incomplete = checkToDoLists(False)
print("COMPLETED ITEMS:")
print(completed)
print("INCOMPLETE ITEMS:")
print(incomplete)

# Test deleted items
found_completed = False
for i in completed:
if test1["Description"] == i["Description"]:
found_completed = True

found_incomplete = False
for i in incomplete:
if test3["Description"] == i["Description"]:
found_incomplete = True

if found_completed == True or found_incomplete == True:
print("FAILED Delete TEST")
else:
print("SUCCESS!")



if __name__ == "__main__":
main()

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
annotations:
vm.kubevirt.io/validations: |
[
{
"name": "minimal-required-memory",
"path": "jsonpath::.spec.domain.memory.guest",
"rule": "integer",
"message": "This VM requires more memory.",
"min": 1073741824
}
]
labels:
app: fedora-close-carp
vm.kubevirt.io/template: fedora-server-small
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.26.0
name: fedora-close-carp
namespace: virttodo
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: fedora-close-carp
spec:
sourceRef:
kind: DataSource
name: fedora
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
running: true
template:
metadata:
annotations:
vm.kubevirt.io/flavor: small
vm.kubevirt.io/os: fedora
vm.kubevirt.io/workload: server
creationTimestamp: null
labels:
kubevirt.io/domain: fedora-close-carp
kubevirt.io/size: small
special: key
spec:
architecture: amd64
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- macAddress: '02:73:43:00:00:07'
masquerade: {}
model: virtio
name: default
networkInterfaceMultiqueue: true
rng: {}
features:
acpi: {}
smm:
enabled: true
firmware:
bootloader:
efi: {}
machine:
type: pc-q35-rhel9.2.0
memory:
guest: 2Gi
resources: {}
networks:
- name: default
pod: {}
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: fedora-close-carp
name: rootdisk
- cloudInitConfigDrive:
userData: |-
#cloud-config
user: fedora
password: dog8code
chpasswd: { expire: False }
user: test
password: dog8code
chpasswd: { expire: False }
packages:
- mariadb-server
- unzip
- wget
runcmd:
- systemctl stop firewalld
- systemctl disable firewalld
- systemctl start mariadb
- systemctl enable mariadb
- mysql -uroot -e "CREATE DATABASE todolist; USE todolist; CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';"
- mysql -uroot -e "grant all privileges on todolist.* to test@'localhost' identified by 'test'; FLUSH PRIVILEGES;"
- pushd /home/test/
- wget https://github.com/weshayutin/todolist-mariadb-go/releases/download/testing3/todolist-linux-amd64.zip
- unzip todolist-linux-amd64.zip
- chown -R test:test /home/test
- semanage fcontext --add --type bin_t '/home/test/todolist-linux-amd64'
- restorecon -Fv /home/test/todolist-linux-amd64
- cp systemd/todolist-mariadb.service /etc/systemd/system/
- popd
- systemctl daemon-reload
- systemctl start todolist-mariadb.service
- systemctl enable todolist-mariadb.service
- systemctl status todolist-mariadb.service
- systemctl disable cloud-init
name: cloudinitdisk
Loading