testcloud 0.9.13__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testcloud-0.9.13 → testcloud-0.10.0}/.gitignore +1 -0
- {testcloud-0.9.13/testcloud.egg-info → testcloud-0.10.0}/PKG-INFO +3 -3
- {testcloud-0.9.13 → testcloud-0.10.0}/README.md +1 -1
- {testcloud-0.9.13 → testcloud-0.10.0}/conf/settings-example.py +2 -0
- testcloud-0.10.0/conf/testcloud +90 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/source/conf.py +1 -1
- testcloud-0.10.0/manpages/testcloud.1 +170 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/requirements.txt +1 -1
- {testcloud-0.9.13 → testcloud-0.10.0}/run_testcloud.py +1 -1
- {testcloud-0.9.13 → testcloud-0.10.0}/setup.py +2 -1
- {testcloud-0.9.13 → testcloud-0.10.0}/test/test_image.py +52 -0
- testcloud-0.10.0/testcloud/__init__.py +18 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/cli.py +4 -17
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/config.py +2 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/domain_configuration.py +2 -1
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/image.py +237 -96
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/instance.py +29 -11
- testcloud-0.10.0/testcloud/sql.py +54 -0
- {testcloud-0.9.13 → testcloud-0.10.0/testcloud.egg-info}/PKG-INFO +3 -3
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud.egg-info/SOURCES.txt +3 -2
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud.egg-info/requires.txt +1 -1
- testcloud-0.9.13/Makefile +0 -133
- testcloud-0.9.13/testcloud/__init__.py +0 -2
- testcloud-0.9.13/testcloud.spec +0 -543
- {testcloud-0.9.13 → testcloud-0.10.0}/LICENSE +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/conf/99-testcloud-nonroot-libvirt-access.rules +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/LICENSE +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/Makefile +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/source/api.rst +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/source/indepth.rst +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/docs/source/index.rst +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/setup.cfg +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/test/__init__.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/test/test_cli.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/test/test_config.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/test/test_instance.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/__init__.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/alma.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/centos.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/debian.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/fedora.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/misc.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/oracle.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/rocky.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/distro_utils/ubuntu.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/exceptions.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/util.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud/workarounds.py +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud.egg-info/dependency_links.txt +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud.egg-info/entry_points.txt +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/testcloud.egg-info/top_level.txt +0 -0
- {testcloud-0.9.13 → testcloud-0.10.0}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: testcloud
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: A tool to download and boot cloud images locally, with an easy to use API.
|
|
5
5
|
Home-page: https://pagure.io/testcloud
|
|
6
6
|
Author: Mike Ruckman
|
|
@@ -8,8 +8,8 @@ Author-email: roshi@fedoraproject.org
|
|
|
8
8
|
License: GPLv2+
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: Jinja2
|
|
12
11
|
Requires-Dist: libvirt-python
|
|
12
|
+
Requires-Dist: peewee
|
|
13
13
|
Requires-Dist: requests
|
|
14
14
|
Requires-Dist: packaging
|
|
15
15
|
Provides-Extra: image-resolve-caching
|
|
@@ -329,7 +329,7 @@ To install **testcloud** for development purposes:
|
|
|
329
329
|
1. Install the dependencies for **testcloud**.
|
|
330
330
|
|
|
331
331
|
```
|
|
332
|
-
$ sudo dnf
|
|
332
|
+
$ sudo dnf builddep testcloud
|
|
333
333
|
```
|
|
334
334
|
|
|
335
335
|
2. Start **libvirtd**.
|
|
@@ -312,7 +312,7 @@ To install **testcloud** for development purposes:
|
|
|
312
312
|
1. Install the dependencies for **testcloud**.
|
|
313
313
|
|
|
314
314
|
```
|
|
315
|
-
$ sudo dnf
|
|
315
|
+
$ sudo dnf builddep testcloud
|
|
316
316
|
```
|
|
317
317
|
|
|
318
318
|
2. Start **libvirtd**.
|
|
@@ -69,6 +69,8 @@
|
|
|
69
69
|
# failing the boot process. Setting this to 0 disables waiting and
|
|
70
70
|
# returns immediately after starting the boot process.
|
|
71
71
|
#BOOT_TIMEOUT = 160
|
|
72
|
+
# timeout after which we should kill unfinished downloads of images
|
|
73
|
+
#IMAGE_DOWNLOAD_TIMEOUT = 1800
|
|
72
74
|
|
|
73
75
|
# Maximum space (in GiB) that unused images can occupy in /var/lib/testcloud/backingstores directory
|
|
74
76
|
# Once the limit is reached, testcloud will attempt to remove oldest files
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
__testcloud()
|
|
2
|
+
{
|
|
3
|
+
local cur prev prev2 prev3 base_opts image_opts instance_opts instance_create_opts
|
|
4
|
+
COMPREPLY=()
|
|
5
|
+
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
6
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
7
|
+
prev2="${COMP_WORDS[COMP_CWORD-2]}"
|
|
8
|
+
prev3="${COMP_WORDS[COMP_CWORD-3]}"
|
|
9
|
+
base_opts="instance image -h --help"
|
|
10
|
+
image_opts="list destroy -h --help"
|
|
11
|
+
instance_opts="list start stop remove create -c -h --help"
|
|
12
|
+
instance_create_opts="-h --ram --no-graphic --vnc --timeout --disksize"
|
|
13
|
+
|
|
14
|
+
echo ${COMP_WORDS[@]} >> /tmp/compwords
|
|
15
|
+
|
|
16
|
+
if [[ ${COMP_WORDS[@]} =~ "testcloud image" || ${COMP_WORDS[@]} =~ "t7d image" ]]; then
|
|
17
|
+
if [[ ${prev} == "image" ]]; then
|
|
18
|
+
COMPREPLY=( $(compgen -W "${image_opts}" -- ${cur}) )
|
|
19
|
+
return 0
|
|
20
|
+
|
|
21
|
+
elif [[ ${prev2} == "image" && ${prev} == "list" ]]; then
|
|
22
|
+
return 0
|
|
23
|
+
|
|
24
|
+
elif [[ ${prev2} == "image" && ${prev} == "destroy" ]]; then
|
|
25
|
+
local images
|
|
26
|
+
images=`testcloud image list 2> /dev/null | grep -E "^ "`
|
|
27
|
+
COMPREPLY=( $(compgen -W "${images}" -- ${cur}) )
|
|
28
|
+
return 0
|
|
29
|
+
|
|
30
|
+
elif [[ ${prev3} == "image" && ${prev2} == "destroy" ]]; then
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
elif [[ ${COMP_WORDS[@]} =~ "testcloud" || ${COMP_WORDS[@]} =~ "t7d" ]]; then
|
|
35
|
+
if [[ ${prev} == "create" ]]; then
|
|
36
|
+
COMPREPLY=( $(compgen -W "${instance_create_opts}" -- ${cur}) )
|
|
37
|
+
return 0
|
|
38
|
+
|
|
39
|
+
elif [[ ${prev} == "remove" ]]; then
|
|
40
|
+
local instances
|
|
41
|
+
instances="`testcloud list | tail -n+3 | head -n-1 | cut -f1 -d' '` --force"
|
|
42
|
+
COMPREPLY=( $(compgen -W "${instances}" -- ${cur}) )
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
elif [[ ${prev2} == "remove" ]]; then
|
|
46
|
+
local instances
|
|
47
|
+
COMPREPLY=( $(compgen -W "--force" -- ${cur}) )
|
|
48
|
+
return 0
|
|
49
|
+
|
|
50
|
+
elif [[ ${prev} == "list" ]]; then
|
|
51
|
+
COMPREPLY=( $(compgen -W "--all" -- ${cur}) )
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
elif [[ ${prev} == "stop" ]]; then
|
|
55
|
+
local instances
|
|
56
|
+
instances=`testcloud list | grep running | cut -f1 -d" "`
|
|
57
|
+
COMPREPLY=( $(compgen -W "${instances}" -- ${cur}) )
|
|
58
|
+
return 0
|
|
59
|
+
|
|
60
|
+
elif [[ ${prev} == "start" ]]; then
|
|
61
|
+
local instances
|
|
62
|
+
instances=`testcloud list | grep shutoff | cut -f1 -d" "`
|
|
63
|
+
COMPREPLY=( $(compgen -W "${instances}" -- ${cur}) )
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
elif [[ ${prev2} == "stop" ]]; then
|
|
67
|
+
return 0
|
|
68
|
+
|
|
69
|
+
elif [[ ${prev2} == "start" ]]; then
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
elif [[ ${COMP_WORDS[@]} =~ " -c" && ! ${COMP_WORDS[@]} =~ "///system" && ! ${COMP_WORDS[@]} =~ "///session" ]]; then
|
|
73
|
+
_get_comp_words_by_ref -n : cur
|
|
74
|
+
COMPREPLY=( $(compgen -W "qemu:///system qemu:///session" -- ${cur}) )
|
|
75
|
+
__ltrim_colon_completions "$cur" # left trim colon (blahblah)
|
|
76
|
+
return 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# fallback
|
|
80
|
+
COMPREPLY=( $(compgen -W "${instance_opts}" -- ${cur}) )
|
|
81
|
+
return 0
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
elif [[ ${cur} == * ]]; then
|
|
85
|
+
COMPREPLY=( $(compgen -W "${base_opts}" -- ${cur}) )
|
|
86
|
+
return 0
|
|
87
|
+
fi
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
complete -F __testcloud testcloud t7d
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
.\" This is the manual page for testcloud.
|
|
2
|
+
.\" Contact lruzicka@redhat.com if you find an errors or a typo.
|
|
3
|
+
.TH TESTCLOUD 1 "11 Nov 2020" "1.0" "testcloud man page"
|
|
4
|
+
.SH NAME
|
|
5
|
+
testcloud \- download \fIqcow2\fR cloud images and boot them locally.
|
|
6
|
+
.SH SYNOPSIS
|
|
7
|
+
\fBtestcloud\fR [-h, --help] [COMMAND]... [OPTION]... [SUBCOMMAND]... [OPTION]...
|
|
8
|
+
.SH DESCRIPTION
|
|
9
|
+
.LP
|
|
10
|
+
\fBtestcloud\fR is a small helper script to download and boot cloud/coreos images
|
|
11
|
+
locally. Testcloud supports wide range of distributions, namely Fedora, Fedora CoreOS,
|
|
12
|
+
CentOS, CentOS Stream, Red Hat Enterprise Linux, Debian and Ubuntu.
|
|
13
|
+
|
|
14
|
+
\fBtestcloud\fR can run either in system mode or in constrained user session mode,
|
|
15
|
+
which is usefull for running it eg. in unprivileged containers.
|
|
16
|
+
.PP
|
|
17
|
+
To run \fBtestcloud\fR, you need to provide the \fBURL\fR of a cloud image or string in \fBdistribution:version\fR format
|
|
18
|
+
to the script which will be used for booting.
|
|
19
|
+
|
|
20
|
+
If you do not have an image location of your own, you can use one
|
|
21
|
+
of the images from the \fBFedora Cloud\fR download pages at \fIhttps://alt.fedoraproject.org/cloud/\fR.
|
|
22
|
+
.PP
|
|
23
|
+
Then, \fBtestcloud\fR will download the image and save it in the \fI/var/lib/testcloud/backingstores/\fR.
|
|
24
|
+
It will use this image to create a backing store for a newly created instance which will be placed in
|
|
25
|
+
\fI/var/tmp/instances/\fR. When the same image has been previously downloaded, \fBtestcloud\fR will NOT
|
|
26
|
+
download it again and it will use the current image to create the instance.
|
|
27
|
+
.PP
|
|
28
|
+
When the new instance is created, \fBtestcloud\fR will show its IP address that you can use to
|
|
29
|
+
access the running instance via \fIssh\fR. The login name is \fBfedora\fR and the password is
|
|
30
|
+
\fBpassw0rd\fR. The IP address of an instance is shown when you list the instance (see COMMANDS).
|
|
31
|
+
.PP
|
|
32
|
+
The instance can also be manipulated and controlled with \fBvirt-manager\fR.
|
|
33
|
+
.SH CONFIGURATION
|
|
34
|
+
The default configuration should work for many people. However, if you need to override the
|
|
35
|
+
default settings, you can do it in the \fIsettings.py\fR file. The example file in
|
|
36
|
+
\fIconf/settings-example.py\fR shows the available configuration values which you can
|
|
37
|
+
alter to suit your needs.
|
|
38
|
+
.PP
|
|
39
|
+
The configuration file must be placed in one of the following locations in order to be
|
|
40
|
+
recognized.
|
|
41
|
+
.IP
|
|
42
|
+
\fIconf/settings.py\fR in the git checkout
|
|
43
|
+
.IP
|
|
44
|
+
\fI~/.config/testcloud/settings.py\fR
|
|
45
|
+
.IP
|
|
46
|
+
\fI/etc/testcloud/settings.py\fR
|
|
47
|
+
.SH COMMANDS
|
|
48
|
+
\fBimage\fR
|
|
49
|
+
Control and manipulate the images (see OPTIONS) for more details.
|
|
50
|
+
.SH OPTIONS
|
|
51
|
+
\fB-h, --help\fR
|
|
52
|
+
Shows the help message and exits.
|
|
53
|
+
|
|
54
|
+
\fB-c CONNECTION, --connection CONNECTION\fR
|
|
55
|
+
Provide the URL of a remote libvirt instance to be used instead of the local one. This option can be used with the \fBinstance\fR command only.
|
|
56
|
+
|
|
57
|
+
.SH SUBCOMMANDS
|
|
58
|
+
\fBcreate\fR
|
|
59
|
+
Create a new instance. See the INSTANCE CREATE OPTIONS section for more details.
|
|
60
|
+
|
|
61
|
+
\fBlist\fR
|
|
62
|
+
List available running instances and images. Use the \fB--all\fR options to list all instances.
|
|
63
|
+
|
|
64
|
+
\fBstart\fR
|
|
65
|
+
Start an existing instance.
|
|
66
|
+
|
|
67
|
+
\fBstop\fR
|
|
68
|
+
Stop a running instance.
|
|
69
|
+
|
|
70
|
+
\fBreboot\fR
|
|
71
|
+
Force the instance to reboot.
|
|
72
|
+
|
|
73
|
+
\fBremove\fR
|
|
74
|
+
Remove an instance or image. If an instance is running, it cannot be removed without the \fB-f\fR option.
|
|
75
|
+
|
|
76
|
+
\fBdestroy\fR
|
|
77
|
+
Remove an instance or image. Deprecated, do not use.
|
|
78
|
+
|
|
79
|
+
\fBclean\fR
|
|
80
|
+
Remove non-existing or unsynced libvirt VMs from testcloud.
|
|
81
|
+
|
|
82
|
+
.SH INSTANCE CREATE OPTIONS
|
|
83
|
+
\fBURL\fR
|
|
84
|
+
Specify the URL from where testcloud should download the instance qcow2 image or distro:version handle. \fBThis option is compulsory\fR.
|
|
85
|
+
Some examples of supported short urls:
|
|
86
|
+
- fedora:rawhide (latest compose), fedora:33, fedora:latest (latest Fedora GA image)
|
|
87
|
+
- fedora-coreos:next, fedora-coreos:testing, fedora-coreos:stable
|
|
88
|
+
- fedora:qa-matrix (image from https://fedoraproject.org/wiki/Test_Results:Current_Cloud_Test )
|
|
89
|
+
- centos:XX (eg. centos:8, centos:latest)
|
|
90
|
+
- centos-stream:XX (eg. centos-stream:8, centos-stream:latest)
|
|
91
|
+
- ubuntu:release_name (eg. ubuntu:focal, ubuntu:latest)
|
|
92
|
+
- debian:release_name/release_number (eg. debian:11, debian:sid, debian:latest)
|
|
93
|
+
|
|
94
|
+
\fB-n, --name NAME\fR
|
|
95
|
+
Set desired instance name. A nice and memorable name will be generated for you if not specified.
|
|
96
|
+
|
|
97
|
+
\fB--arch ARCH\fR
|
|
98
|
+
Set the desired guest architecture. Host arch is the default, supported are: x86_64, aarch64, ppc64le, and s390x.
|
|
99
|
+
|
|
100
|
+
\fB--ram RAM\fR
|
|
101
|
+
Set the amount of RAM that will be available to the instance's VM (in MiB).
|
|
102
|
+
|
|
103
|
+
\fB--vcpus VCPUS\fR
|
|
104
|
+
Set the number of virtual CPU cores to be assinged to the VM.
|
|
105
|
+
|
|
106
|
+
\fB--disksize DISKSIZE\fR
|
|
107
|
+
Set the disk size of the instance VM (in GiB).
|
|
108
|
+
|
|
109
|
+
\fB--vnc\fR
|
|
110
|
+
Open a VNC connection to the \fB:1\fR display of the instance VM.
|
|
111
|
+
|
|
112
|
+
\fB--no-graphic\fR
|
|
113
|
+
Turn off the instance VM's graphical display.
|
|
114
|
+
|
|
115
|
+
\fB--timeout TIMEOUT\fR
|
|
116
|
+
Specify the time (in seconds) to wait for the instance boot to complete. To disable waiting time (default behaviour) set to \fB0\fR.
|
|
117
|
+
|
|
118
|
+
\fB--disk_number\fR
|
|
119
|
+
\fB:\fR To provide disk number you want
|
|
120
|
+
|
|
121
|
+
\fB--nic_number\fR
|
|
122
|
+
\fB:\fR To provide nic number you want
|
|
123
|
+
|
|
124
|
+
\fB--virtiofs\fR
|
|
125
|
+
\fB:\fR To specify a local directory to mount and mount target like <host path>:<guest path>
|
|
126
|
+
|
|
127
|
+
\fB--iommu\fR
|
|
128
|
+
\fB:\fR To provide virtual iommu device
|
|
129
|
+
|
|
130
|
+
\fB ADDITIONAL COREOS OPTIONS\fR
|
|
131
|
+
|
|
132
|
+
\fB--bu_file BU_FILE\fR
|
|
133
|
+
\fB:\fR To provide a bu_file you want to use
|
|
134
|
+
|
|
135
|
+
\fB--ign_file IGN_FILE\fR
|
|
136
|
+
\fB:\fR To provide an ign_file you want to use
|
|
137
|
+
|
|
138
|
+
\fB--ssh_path\fR
|
|
139
|
+
\fB:\fR To provide a ssh pubkey path you want to use
|
|
140
|
+
|
|
141
|
+
.SH EXAMPLES
|
|
142
|
+
.PP
|
|
143
|
+
Create a new instance:
|
|
144
|
+
.IP
|
|
145
|
+
\fBtestcloud create <URL>\fR
|
|
146
|
+
.PP
|
|
147
|
+
List all available instances:
|
|
148
|
+
.IP
|
|
149
|
+
\fBtestcloud list\fR
|
|
150
|
+
.PP
|
|
151
|
+
Start an existing instance:
|
|
152
|
+
.IP
|
|
153
|
+
\fBtestcloud start <instance_name>\fR
|
|
154
|
+
.PP
|
|
155
|
+
Stop an existing instance:
|
|
156
|
+
.IP
|
|
157
|
+
\fBtestcloud stop <instance_name>\fR
|
|
158
|
+
.PP
|
|
159
|
+
Remove a running instance:
|
|
160
|
+
.IP
|
|
161
|
+
\fBtestcloud remove -f <instance_name>\fR
|
|
162
|
+
|
|
163
|
+
.SH SEE ALSO
|
|
164
|
+
|
|
165
|
+
\fBtestcloud's help\fR and the Project's \fBREADME.md\fR file
|
|
166
|
+
|
|
167
|
+
.SH BUGS
|
|
168
|
+
No known bugs. If you have found a bug, please report it at \fIhttps://bugzilla.redhat.com\fR.
|
|
169
|
+
.SH AUTHOR
|
|
170
|
+
Mike Ruckman (roshi@fedoraproject.org)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# This is a list of pypi packages to be installed into virtualenv. Alternatively,
|
|
2
2
|
# you can install these as RPMs instead of pypi packages. See README.
|
|
3
3
|
|
|
4
|
-
Jinja2
|
|
5
4
|
libvirt-python
|
|
6
5
|
requests
|
|
6
|
+
peewee
|
|
7
7
|
#guestfs - after it is on pypi ( https://bugzilla.redhat.com/show_bug.cgi?id=1075594 )
|
|
8
8
|
|
|
9
9
|
# Test suite requirements
|
|
@@ -50,9 +50,10 @@ setup(name='testcloud',
|
|
|
50
50
|
include_package_data=True,
|
|
51
51
|
cmdclass={'test': PyTest},
|
|
52
52
|
entry_points=dict(console_scripts=["testcloud=testcloud.cli:main", "t7d=testcloud.cli:main"]),
|
|
53
|
+
data_files = [('share/man/man1', ['manpages/testcloud.1']), ('share/bash-completion/completions', ['conf/testcloud'])],
|
|
53
54
|
install_requires=[
|
|
54
|
-
'Jinja2',
|
|
55
55
|
'libvirt-python',
|
|
56
|
+
'peewee',
|
|
56
57
|
'requests',
|
|
57
58
|
'packaging'
|
|
58
59
|
],
|
|
@@ -52,6 +52,44 @@ class TestImageUriProcess(object):
|
|
|
52
52
|
assert test_data['name'] == self.image_name
|
|
53
53
|
assert test_data['path'] == ref_path
|
|
54
54
|
|
|
55
|
+
# def test_http_ur1_params(self):
|
|
56
|
+
# ref_type = 'http'
|
|
57
|
+
# ref_path = 'localhost/images/{}'.format(self.image_name)
|
|
58
|
+
# ref_uri = '{}://{}?url_param=value'.format(ref_type, ref_path)
|
|
59
|
+
#
|
|
60
|
+
# test_image = image.Image(ref_uri)
|
|
61
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
62
|
+
#
|
|
63
|
+
# assert test_data['type'] == ref_type
|
|
64
|
+
# assert test_data['name'] == self.image_name
|
|
65
|
+
# assert test_data['path'] == ref_path
|
|
66
|
+
#
|
|
67
|
+
# def test_http_ur1_anchor(self):
|
|
68
|
+
# ref_type = 'http'
|
|
69
|
+
# ref_path = 'localhost/images/{}'.format(self.image_name)
|
|
70
|
+
# ref_uri = '{}://{}#anchor'.format(ref_type, ref_path)
|
|
71
|
+
#
|
|
72
|
+
# test_image = image.Image(ref_uri)
|
|
73
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
74
|
+
#
|
|
75
|
+
# assert test_data['type'] == ref_type
|
|
76
|
+
# assert test_data['name'] == self.image_name
|
|
77
|
+
# assert test_data['path'] == ref_path
|
|
78
|
+
#
|
|
79
|
+
#
|
|
80
|
+
# def test_http_ur1_url_quoted(self):
|
|
81
|
+
# ref_type = 'http'
|
|
82
|
+
# ref_path = 'localhost/images/image%20name.img'
|
|
83
|
+
# ref_uri = '{}://{}'.format(ref_type, ref_path)
|
|
84
|
+
#
|
|
85
|
+
# test_image = image.Image(ref_uri)
|
|
86
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
87
|
+
#
|
|
88
|
+
# assert test_data['type'] == ref_type
|
|
89
|
+
# assert test_data['name'] == "image name.img"
|
|
90
|
+
# assert test_data['path'] == ref_path
|
|
91
|
+
|
|
92
|
+
|
|
55
93
|
def test_https_uri(self):
|
|
56
94
|
ref_type = 'https'
|
|
57
95
|
ref_path = 'localhost/images/{}'.format(self.image_name)
|
|
@@ -78,6 +116,20 @@ class TestImageUriProcess(object):
|
|
|
78
116
|
assert test_data['name'] == self.image_name
|
|
79
117
|
assert test_data['path'] == ref_path
|
|
80
118
|
|
|
119
|
+
# def test_box(self):
|
|
120
|
+
# ref_uri = "http://local.host/file.box"
|
|
121
|
+
# test_image = image.Image(ref_uri)
|
|
122
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
123
|
+
# assert test_data['name'] == "file.qcow2"
|
|
124
|
+
#
|
|
125
|
+
#
|
|
126
|
+
# def test_xz(self):
|
|
127
|
+
# ref_uri = "http://local.host/file.iso.xz"
|
|
128
|
+
# test_image = image.Image(ref_uri)
|
|
129
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
130
|
+
# assert test_data['name'] == "file.iso"
|
|
131
|
+
|
|
132
|
+
|
|
81
133
|
def test_invalid_uri_type(self):
|
|
82
134
|
ref_type = 'ftp'
|
|
83
135
|
ref_path = '/localhost/images/{}'.format(self.image_name)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# NOTE: if you update version, *make sure* to also update `docs/source/conf.py`
|
|
2
|
+
__version__ = "0.10.0"
|
|
3
|
+
|
|
4
|
+
import signal
|
|
5
|
+
import sys
|
|
6
|
+
import threading
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def sigterm_handler(_signo, _stack_frame):
|
|
10
|
+
# A call to sys.exit() is translated into an exception so that clean-up handlers
|
|
11
|
+
# (finally clauses of try statements) can be executed, and so that a debugger can
|
|
12
|
+
# execute a script without running the risk of losing control.
|
|
13
|
+
sys.exit(0)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if threading.current_thread() is threading.main_thread():
|
|
18
|
+
signal.signal(signal.SIGTERM, sigterm_handler)
|
|
@@ -80,9 +80,6 @@ def _handle_connection_tip(ip, port, vagrant=False):
|
|
|
80
80
|
print("ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null cloud-user@%s -p %d" % (ip, port))
|
|
81
81
|
|
|
82
82
|
print("-"*80)
|
|
83
|
-
if port != 22:
|
|
84
|
-
print("Due to limitations of tescloud's user session VMs and bugs in some systems,"
|
|
85
|
-
" the ssh connection may not be available immediately...")
|
|
86
83
|
if vagrant:
|
|
87
84
|
print("Due to limited support for images without cloud-init pre installed,"
|
|
88
85
|
"it may take up to 2 minutes for connection to be ready...")
|
|
@@ -96,9 +93,6 @@ def _handle_permissions_error_cli(error):
|
|
|
96
93
|
print("su - $USER")
|
|
97
94
|
sys.exit(1)
|
|
98
95
|
|
|
99
|
-
def _bail_from_legacy_cli(args):
|
|
100
|
-
log.error("instance subcommand was removed from testcloud. For instance operations, omit the 'instance' keyword.")
|
|
101
|
-
|
|
102
96
|
def _list_instance(args):
|
|
103
97
|
"""Handler for 'list' command. Expects the following elements in args:
|
|
104
98
|
* name(str)
|
|
@@ -286,15 +280,14 @@ def _download_image(args):
|
|
|
286
280
|
sys.exit(1)
|
|
287
281
|
|
|
288
282
|
try:
|
|
283
|
+
# FIXME maybe change to smth like ... if args.url[:4] not in ["http", "file"]
|
|
289
284
|
url = get_image_url(args.url, arch=args.arch) if not any([prot in args.url for prot in ["http", "file"]]) else args.url
|
|
290
285
|
except TestcloudImageError:
|
|
291
286
|
log.error("Couldn't find the desired image ( %s )..." % args.url)
|
|
292
287
|
sys.exit(1)
|
|
293
288
|
|
|
294
|
-
tc_image = image.Image(url)
|
|
295
|
-
|
|
296
289
|
try:
|
|
297
|
-
|
|
290
|
+
image.Image._download_remote_image(url, os.path.join(args.dest_path, os.path.basename(urlparse(url).path)))
|
|
298
291
|
except TestcloudImageError:
|
|
299
292
|
log.error("Couldn't download the requested image due to an error.")
|
|
300
293
|
sys.exit(1)
|
|
@@ -628,7 +621,6 @@ def _list_image(args):
|
|
|
628
621
|
for img in images:
|
|
629
622
|
print(" {}".format(img))
|
|
630
623
|
|
|
631
|
-
|
|
632
624
|
def _remove_image(args):
|
|
633
625
|
"""Handler for 'image remove' command. Expects the following elements in args:
|
|
634
626
|
* name(str)
|
|
@@ -642,6 +634,7 @@ def _remove_image(args):
|
|
|
642
634
|
|
|
643
635
|
if tc_image is None:
|
|
644
636
|
log.error("image {} not found, cannot remove".format(args.name))
|
|
637
|
+
return
|
|
645
638
|
|
|
646
639
|
tc_image.remove()
|
|
647
640
|
|
|
@@ -652,13 +645,6 @@ def get_argparser():
|
|
|
652
645
|
description="Types of commands available",
|
|
653
646
|
help="<command> --help")
|
|
654
647
|
|
|
655
|
-
instarg_legacy = subparsers.add_parser("instance", help="help on instance options")
|
|
656
|
-
instarg_legacy.set_defaults(func=_bail_from_legacy_cli)
|
|
657
|
-
|
|
658
|
-
instarg_legacy.add_argument("anything",
|
|
659
|
-
type=str,
|
|
660
|
-
nargs='*')
|
|
661
|
-
|
|
662
648
|
parser.add_argument("-c",
|
|
663
649
|
"--connection",
|
|
664
650
|
default="qemu:///system",
|
|
@@ -842,6 +828,7 @@ def get_argparser():
|
|
|
842
828
|
imgarg_list = imgarg_subp.add_parser("list", help="list images")
|
|
843
829
|
imgarg_list.set_defaults(func=_list_image)
|
|
844
830
|
|
|
831
|
+
|
|
845
832
|
# image remove
|
|
846
833
|
imgarg_remove = imgarg_subp.add_parser('remove', help="remove image")
|
|
847
834
|
imgarg_remove.add_argument("name",
|
|
@@ -157,6 +157,8 @@ storage:
|
|
|
157
157
|
CMD_LINE_ENVS_COREOS = {}
|
|
158
158
|
# timeout, in seconds for instance boot process
|
|
159
159
|
BOOT_TIMEOUT = 160
|
|
160
|
+
# timeout after which we should kill unfinished downloads of images
|
|
161
|
+
IMAGE_DOWNLOAD_TIMEOUT = 1800
|
|
160
162
|
|
|
161
163
|
# Maximum space (in GiB) that unused images can occupy in /var/lib/testcloud/backingstores directory
|
|
162
164
|
# Once the limit is reached, testcloud will attempt to remove oldest files
|
|
@@ -222,7 +222,8 @@ class UserNetworkConfiguration(NetworkConfiguration):
|
|
|
222
222
|
def __init__(self, mac_address, port=6666, device_type="virtio-net-pci") -> None:
|
|
223
223
|
super().__init__()
|
|
224
224
|
self.mac_address = mac_address
|
|
225
|
-
self.additional_qemu_args = ["-netdev", "user,id=testcloud_net.{},hostfwd=tcp::{}-:22".format(
|
|
225
|
+
self.additional_qemu_args = ["-netdev", "user,id=testcloud_net.{},hostfwd=tcp::{}-:22,hostfwd=tcp::{}-:10022".format(
|
|
226
|
+
port, port, (port-1000)),
|
|
226
227
|
"-device", "{},addr=1e.0,netdev=testcloud_net.{}".format(device_type, port)]
|
|
227
228
|
|
|
228
229
|
def generate(self):
|