Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Cédric Le Ninivin
slapos
Commits
fd11c057
Commit
fd11c057
authored
Apr 17, 2012
by
Mohamadou Mbengue
Browse files
Options
Browse Files
Download
Plain Diff
Merge master in lamp-mohamadou branch
parents
7bfbb73a
d49bf561
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
666 additions
and
139 deletions
+666
-139
CHANGES.txt
CHANGES.txt
+7
-1
component/firefox/buildout.cfg
component/firefox/buildout.cfg
+5
-3
component/fontconfig/buildout.cfg
component/fontconfig/buildout.cfg
+1
-0
component/gtk-2/buildout.cfg
component/gtk-2/buildout.cfg
+6
-5
component/xorg/buildout.cfg
component/xorg/buildout.cfg
+84
-33
component/xorg/tmp_env.patch
component/xorg/tmp_env.patch
+30
-0
component/xorg/xcb_tmp_env.patch
component/xorg/xcb_tmp_env.patch
+36
-0
component/xorg/xtrans_tmp_env.patch
component/xorg/xtrans_tmp_env.patch
+64
-0
setup.py
setup.py
+3
-1
slapos/recipe/firefox/__init__.py
slapos/recipe/firefox/__init__.py
+51
-0
slapos/recipe/firefox/template/firefox_run.in
slapos/recipe/firefox/template/firefox_run.in
+55
-0
slapos/recipe/firefox/template/prefs.js
slapos/recipe/firefox/template/prefs.js
+55
-0
slapos/recipe/seleniumrunner/__init__.py
slapos/recipe/seleniumrunner/__init__.py
+12
-72
slapos/recipe/seleniumrunner/testrunner.py
slapos/recipe/seleniumrunner/testrunner.py
+29
-16
slapos/recipe/xvfb/__init__.py
slapos/recipe/xvfb/__init__.py
+56
-0
slapos/recipe/xvfb/template/xvfb_run.in
slapos/recipe/xvfb/template/xvfb_run.in
+6
-0
slapos/recipe/xvfb/template/xwd_run.in
slapos/recipe/xvfb/template/xwd_run.in
+7
-0
software/seleniumrunner/instance-selenium.cfg
software/seleniumrunner/instance-selenium.cfg
+47
-0
software/seleniumrunner/instance.cfg
software/seleniumrunner/instance.cfg
+15
-6
software/seleniumrunner/software.cfg
software/seleniumrunner/software.cfg
+97
-2
No files found.
CHANGES.txt
View file @
fd11c057
Changes
Changes
=======
=======
0.4
6
(Unreleased)
0.4
7
(Unreleased)
-----------------
-----------------
* No change yet.
* No change yet.
0.46 (2012/04/12)
-----------------
* xvfb and firefox initial release [Romain Courteaud]
0.45 (2012-03-29)
0.45 (2012-03-29)
-----------------
-----------------
...
...
component/firefox/buildout.cfg
View file @
fd11c057
...
@@ -6,6 +6,8 @@ extends =
...
@@ -6,6 +6,8 @@ extends =
../dbus/buildout.cfg
../dbus/buildout.cfg
../gtk-2/buildout.cfg
../gtk-2/buildout.cfg
../libpng/buildout.cfg
../libpng/buildout.cfg
../dash/buildout.cfg
../openssl/buildout.cfg
parts =
parts =
firefox
firefox
...
@@ -30,11 +32,11 @@ script =
...
@@ -30,11 +32,11 @@ script =
self.copyTree(workdir, "%(location)s")
self.copyTree(workdir, "%(location)s")
wrapper_location = os.path.join("%(location)s", "firefox-slapos")
wrapper_location = os.path.join("%(location)s", "firefox-slapos")
wrapper = open(wrapper_location, 'w')
wrapper = open(wrapper_location, 'w')
wrapper.write("""#!
/bin/
sh
wrapper.write("""#!
${dash:location}/bin/da
sh
cd %(location)s
cd %(location)s
export LD_LIBRARY_PATH=
${libXrender:location}/lib/:${fontconfig:location}/lib/:${dbus:location}/lib/:${dbus-glib:location}/lib/:${pango:location}/lib:${cairo:location}/lib:${glib:location}/lib:${gtk-2:location}/lib:${atk:location}/lib:${gdk-pixbuf:location}/lib:${libXt:location}/lib:${libpng:location}/lib:${libSM:location}/lib:${libICE:location}/lib:${alsa:location}/lib:%(location)s
export LD_LIBRARY_PATH=
%(location)s:${libXrender:location}/lib/:${freetype:location}/lib/:${fontconfig:location}/lib/:${libX11:location}/lib/:${bzip2:location}/lib/:${libXext:location}/lib/:${libXt:location}/lib/:${zlib:location}/lib/:${libXcursor:location}/lib/:${gtk-2:location}/lib/:${cairo:location}/lib/:${pango:location}/lib/:${glib:location}/lib/:${atk:location}/lib/:${gdk-pixbuf:location}/lib/:${alsa:location}/lib/:${libpng:location}/lib/:${libSM:location}/lib/:${libICE:location}/lib:${libxml2:location}/lib:${openssl:location}/lib
export PATH=${fontconfig:location}/bin:$PATH
export PATH=${fontconfig:location}/bin:$PATH
%(location)s/firefox $*""")
exec
%(location)s/firefox $*""")
wrapper.close()
wrapper.close()
os.chmod(wrapper_location, 0777)
os.chmod(wrapper_location, 0777)
component/fontconfig/buildout.cfg
View file @
fd11c057
...
@@ -6,6 +6,7 @@ extends =
...
@@ -6,6 +6,7 @@ extends =
../pkgconfig/buildout.cfg
../pkgconfig/buildout.cfg
../bzip2/buildout.cfg
../bzip2/buildout.cfg
../zlib/buildout.cfg
../zlib/buildout.cfg
../bzip2/buildout.cfg
parts =
parts =
fontconfig
fontconfig
...
...
component/gtk-2/buildout.cfg
View file @
fd11c057
...
@@ -37,8 +37,8 @@ configure-options =
...
@@ -37,8 +37,8 @@ configure-options =
environment =
environment =
PATH=${glib:location}/bin:${freetype:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PATH=${glib:location}/bin:${freetype:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig::${libXrender:location}/lib/pkgconfig
PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig::${libXrender:location}/lib/pkgconfig
CPPFLAGS=-I${cairo:location}/include/cairo
CPPFLAGS=-I${cairo:location}/include/cairo
-I${libX11:location}/include/X11 -I${libxcb:location}/include/xcb -I${libXau:location}/include/X11 -I${bzip2:location}/include -L${libXrender:location}/include -I${zlib:location}/include
LDFLAGS=-L${
zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib -lXrender
LDFLAGS=-L${
cairo:location}/lib -Wl,-rpath=${cairo:location}/lib -L${libX11:location}/lib -Wl,-rpath=${libX11:location}/lib -L${libxcb:location}/lib -Wl,-rpath=${libxcb:location}/lib -L${libXau:location}/lib -Wl,-rpath=${libXau:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib -lXrender -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
LD_LIBRARY_PATH=${render:location}/lib:${libX11:location}/lib:${libXrender:location}/lib
LD_LIBRARY_PATH=${render:location}/lib:${libX11:location}/lib:${libXrender:location}/lib
[gdk-pixbuf]
[gdk-pixbuf]
...
@@ -74,9 +74,10 @@ configure-options =
...
@@ -74,9 +74,10 @@ configure-options =
--disable-cups
--disable-cups
--disable-papi
--disable-papi
--enable-explicit-deps
--enable-explicit-deps
--disable-xinerama
environment =
environment =
PATH=${gdk-pixbuf:location}/bin:${glib:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PATH=${gdk-pixbuf:location}/bin:${glib:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${
gettext:location}/lib/pkgconfig:${
fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig:${atk:location}/lib/pkgconfig:${gdk-pixbuf:location}/lib/pkgconfig:${pango:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${pixman:location}/lib/pkgconfig:${libpng:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xcbproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig
PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig:${atk:location}/lib/pkgconfig:${gdk-pixbuf:location}/lib/pkgconfig:${pango:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${pixman:location}/lib/pkgconfig:${libpng:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xcbproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig
CPPFLAGS=-I${libtiff:location}/include -I${libjpeg:location}/include -I${libpng:location}/include -I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include -I${libXext:location}/include -I${cairo:location}/include/cairo
CPPFLAGS=-I${libtiff:location}/include -I${libjpeg:location}/include -I${libpng:location}/include -I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include -I${libXext:location}/include -I${cairo:location}/include/cairo
-I${zlib:location}/include -I${bzip2:location}/include -I${libXdmcp:location}/include -I${glib:location}/include/gio-unix-2.0 -I${glib:location}/include/glib-2.0 -I${glib:location}/include -I${atk:location}/include/atk-1.0
LDFLAGS=-L${
gettext:location}/lib -L${glib:location}/lib -L${libtiff:location}/lib -L${libjpeg:location}/lib -L${libpng:location}/lib -L${zlib:location}/lib -L${libXrender:location}/lib -L${libX11:location}/lib -L${libXext:location}/lib -L${pango
:location}/lib
LDFLAGS=-L${
libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${libX11:location}/lib -Wl,-rpath=${libX11:location}/lib -L${xproto:location}/lib -Wl,-rpath=${xproto:location}/lib -L${kbproto:location}/lib -Wl,-rpath=${kbproto:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib -L${render:location}/lib -Wl,-rpath=${render:location}/lib -L${libXext:location}/lib -Wl,-rpath=${libXext:location}/lib -L${cairo:location}/lib -Wl,-rpath=${cairo:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${libXdmcp:location}/lib -Wl,-rpath=${libXdmcp:location}/lib -L${glib:location}/lib -Wl,-rpath=${glib:location}/lib -L${atk:location}/lib -Wl,-rpath=${atk:location}/lib -L${gettext:location}/lib -Wl,-rpath=${gettext
:location}/lib
LD_LIBRARY_PATH=${glib:location}/lib:${gettext:location}/lib:${libX11:location}/lib
LD_LIBRARY_PATH=${glib:location}/lib:${gettext:location}/lib:${libX11:location}/lib
component/xorg/buildout.cfg
View file @
fd11c057
This diff is collapsed.
Click to expand it.
component/xorg/tmp_env.patch
0 → 100644
View file @
fd11c057
--- xorg-server-1.9.3/os/utils.c.old 2012-03-29 18:20:02.000000000 +0200
+++ xorg-server-1.9.3/os/utils.c 2012-03-29 18:39:33.000000000 +0200
@@ -226,7 +226,26 @@
OsSignal(int sig, OsSigHandlerPtr handle
* server at a time. This keeps the servers from stomping on each other
* if the user forgets to give them different display numbers.
*/
-#define LOCK_DIR "/tmp"
+char *
+getcompatibleenv(const char *name, const char *compatible)
+{
+ static char path_list[1][PATH_MAX];
+ char *dir;
+
+ if (path_list[0][0]) {
+ return path_list[0];
+ }
+
+ dir = getenv(name);
+ if (dir == NULL) {
+ return strncpy(path_list[0], compatible, PATH_MAX);
+ } else {
+ return strncpy(path_list[0], dir, PATH_MAX);
+ }
+
+}
+
+#define LOCK_DIR getcompatibleenv("TMPDIR", "/tmp")
#define LOCK_TMP_PREFIX "/.tX"
#define LOCK_PREFIX "/.X"
#define LOCK_SUFFIX "-lock"
component/xorg/xcb_tmp_env.patch
0 → 100644
View file @
fd11c057
--- libxcb-1.7/src/xcb_util.c.back 2012-04-03 13:30:36.000000000 +0200
+++ libxcb-1.7/src/xcb_util.c 2012-04-03 14:47:00.000000000 +0200
@@ -147,11 +147,31 @@
static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
#endif
+char *
+_xcb_getandappendcompatibleenv(const char *name, const char *compatible, const char *suffix)
+{
+ static char path_list[1][PATH_MAX];
+ char *dir;
+
+ if (path_list[0][0])
+ {
+ return path_list[0];
+ }
+
+ dir = getenv(name);
+ if (dir == NULL) {
+ strncpy(path_list[0], compatible, PATH_MAX);
+ } else {
+ strncpy(path_list[0], dir, PATH_MAX);
+ }
+ return strncat(path_list[0], suffix, PATH_MAX);
+}
+
static int _xcb_open(const char *host, char *protocol, const int display)
{
int fd;
- static const char unix_base[] = "/tmp/.X11-unix/X";
- const char *base = unix_base;
+ char *base;
+ base = _xcb_getandappendcompatibleenv("TMPDIR", "/tmp", "/.X11-unix/X");
size_t filelen;
char *file = NULL;
int actual_filelen;
component/xorg/xtrans_tmp_env.patch
0 → 100644
View file @
fd11c057
--- xtrans-1.2.6/Xtranssock.c.old 2012-03-29 14:25:45.000000000 +0200
+++ xtrans-1.2.6/Xtranssock.c 2012-03-29 18:40:54.000000000 +0200
@@ -207,29 +207,49 @@
static int TRANS(SocketINETClose) (Xtran
#ifdef UNIXCONN
+char *
+getandappendcompatibleenv(const int index, const char *name, const char *compatible, const char *suffix)
+{
+ static char path_list[2][PATH_MAX];
+ char *dir;
+
+ if (path_list[index][0])
+ {
+ return path_list[index];
+ }
+
+ dir = getenv(name);
+ if (dir == NULL) {
+ strncpy(path_list[index], compatible, PATH_MAX);
+ } else {
+ strncpy(path_list[index], dir, PATH_MAX);
+ }
+ return strncat(path_list[index], suffix, PATH_MAX);
+}
+
#if defined(X11_t)
-#define UNIX_PATH "/tmp/.X11-unix/X"
-#define UNIX_DIR "/tmp/.X11-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.X11-unix/X")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.X11-unix")
#endif /* X11_t */
#if defined(XIM_t)
-#define UNIX_PATH "/tmp/.XIM-unix/XIM"
-#define UNIX_DIR "/tmp/.XIM-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.XIM-unix/XIM")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.XIM-unix")
#endif /* XIM_t */
#if defined(FS_t) || defined(FONT_t)
-#define UNIX_PATH "/tmp/.font-unix/fs"
-#define UNIX_DIR "/tmp/.font-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.font-unix/fs")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.font-unix")
#endif /* FS_t || FONT_t */
#if defined(ICE_t)
-#define UNIX_PATH "/tmp/.ICE-unix/"
-#define UNIX_DIR "/tmp/.ICE-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.ICE-unix/")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.ICE-unix")
#endif /* ICE_t */
#if defined(TEST_t)
-#define UNIX_PATH "/tmp/.Test-unix/test"
-#define UNIX_DIR "/tmp/.Test-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.Test-unix/test")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.Test-unix")
#endif
#if defined(LBXPROXY_t)
-#define UNIX_PATH "/tmp/.X11-unix/X"
-#define UNIX_DIR "/tmp/.X11-unix"
+#define UNIX_PATH getandappendcompatibleenv(0, "TMPDIR", "/tmp", "/.X11-unix/X")
+#define UNIX_DIR getandappendcompatibleenv(1, "TMPDIR", "/tmp", "/.X11-unix")
#endif
setup.py
View file @
fd11c057
...
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
...
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import
glob
import
glob
import
os
import
os
version
=
'0.4
6
-dev'
version
=
'0.4
7
-dev'
name
=
'slapos.cookbook'
name
=
'slapos.cookbook'
long_description
=
open
(
"README.txt"
).
read
()
+
"
\
n
"
+
\
long_description
=
open
(
"README.txt"
).
read
()
+
"
\
n
"
+
\
open
(
"CHANGES.txt"
).
read
()
+
"
\
n
"
open
(
"CHANGES.txt"
).
read
()
+
"
\
n
"
...
@@ -62,6 +62,7 @@ setup(name=name,
...
@@ -62,6 +62,7 @@ setup(name=name,
'generic.onetimeupload = slapos.recipe.generic_onetimeupload:Recipe'
,
'generic.onetimeupload = slapos.recipe.generic_onetimeupload:Recipe'
,
'helloworld = slapos.recipe.helloworld:Recipe'
,
'helloworld = slapos.recipe.helloworld:Recipe'
,
'generic.cloudooo = slapos.recipe.generic_cloudooo:Recipe'
,
'generic.cloudooo = slapos.recipe.generic_cloudooo:Recipe'
,
'firefox = slapos.recipe.firefox:Recipe'
,
'fontconfig = slapos.recipe.fontconfig:Recipe'
,
'fontconfig = slapos.recipe.fontconfig:Recipe'
,
'java = slapos.recipe.java:Recipe'
,
'java = slapos.recipe.java:Recipe'
,
'kumofs = slapos.recipe.kumofs:Recipe'
,
'kumofs = slapos.recipe.kumofs:Recipe'
,
...
@@ -112,6 +113,7 @@ setup(name=name,
...
@@ -112,6 +113,7 @@ setup(name=name,
'urlparse = slapos.recipe._urlparse:Recipe'
,
'urlparse = slapos.recipe._urlparse:Recipe'
,
'vifib = slapos.recipe.vifib:Recipe'
,
'vifib = slapos.recipe.vifib:Recipe'
,
'waitfor = slapos.recipe.waitfor:Recipe'
,
'waitfor = slapos.recipe.waitfor:Recipe'
,
'xvfb = slapos.recipe.xvfb:Recipe'
,
'xwiki = slapos.recipe.xwiki:Recipe'
,
'xwiki = slapos.recipe.xwiki:Recipe'
,
'zabbixagent = slapos.recipe.zabbixagent:Recipe'
,
'zabbixagent = slapos.recipe.zabbixagent:Recipe'
,
'generic.zope = slapos.recipe.generic_zope:Recipe'
,
'generic.zope = slapos.recipe.generic_zope:Recipe'
,
...
...
slapos/recipe/firefox/__init__.py
0 → 100644
View file @
fd11c057
##############################################################################
#
# Copyright (c) 2012 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#############################################################################
from
slapos.recipe.librecipe
import
GenericBaseRecipe
import
sys
class
Recipe
(
GenericBaseRecipe
):
def
install
(
self
):
prefjs
=
self
.
createFile
(
self
.
options
[
'prefsjs-path'
],
self
.
substituteTemplate
(
self
.
getTemplateFilename
(
'prefs.js'
),
{}))
config
=
{
'firefox_binary'
:
self
.
options
[
'firefox-path'
],
'python_path'
:
sys
.
executable
,
'tmp_path'
:
self
.
options
[
'tmp-path'
],
'pref_path'
:
prefjs
,
}
runner
=
self
.
createExecutable
(
self
.
options
[
'runner-path'
],
self
.
substituteTemplate
(
self
.
getTemplateFilename
(
'firefox_run.in'
),
config
))
return
[
runner
,
prefjs
]
slapos/recipe/firefox/template/firefox_run.in
0 → 100644
View file @
fd11c057
#!%(python_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
#
import os
from subprocess import Popen, PIPE
import tempfile
import shutil
import sys
import signal
import subprocess
import time
os.environ['MOZ_NO_REMOTE'] = '1'
os.environ['LC_ALL'] = 'C'
os.environ['MOZ_CRASHREPORTER_DISABLE'] = '1'
os.environ['NO_EM_RESTART'] = '1'
os.environ['TMPDIR'] = "%(tmp_path)s"
os.environ['DISPLAY'] = ':0'
# XXX .Xauthority
profile_path = tempfile.mkdtemp()
shutil.copyfile('%(pref_path)s', os.path.join(profile_path, 'pref.js'))
# os.environ['HOME'] = profile_path
child_pg = None
def sig_handler(signal, frame):
if child_pg is not None:
os.killpg(child_pg, signal.SIGHUP)
os.killpg(child_pg, signal.SIGTERM)
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGQUIT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
def execute_with_signal_translation(args):
"""Run process as children and translate from SIGTERM to another signal"""
child = subprocess.Popen(args, close_fds=True, preexec_fn=os.setsid)
child_pg = child.pid
try:
while True:
time.sleep(2)
finally:
os.killpg(child_pg, signal.SIGHUP)
os.killpg(child_pg, signal.SIGTERM)
try:
execute_with_signal_translation(
["%(firefox_binary)s", "-no-remote", "-profile", profile_path] + sys.argv[1:])
finally:
shutil.rmtree(profile_path)
slapos/recipe/firefox/template/prefs.js
0 → 100644
View file @
fd11c057
// Don't ask if we want to switch default browsers
user_pref
(
"
browser.shell.checkDefaultBrowser
"
,
false
);
user_pref
(
"
browser.startup.homepage_override.mstone
"
,
"
ignore
"
);
// disable application updates
user_pref
(
"
app.update.enabled
"
,
false
)
// disables the 'know your rights' button from displaying on first run
user_pref
(
"
browser.rights.3.shown
"
,
true
);
// Disable pop-up blocking
user_pref
(
"
browser.allowpopups
"
,
true
);
user_pref
(
"
dom.disable_open_during_load
"
,
false
);
user_pref
(
"
browser.tabs.warnOnClose
"
,
false
);
// Configure us as the local proxy
//user_pref("network.proxy.type", 2);
// Disable security warnings
user_pref
(
"
security.warn_submit_insecure
"
,
false
);
user_pref
(
"
security.warn_submit_insecure.show_once
"
,
false
);
user_pref
(
"
security.warn_entering_secure
"
,
false
);
user_pref
(
"
security.warn_entering_secure.show_once
"
,
false
);
user_pref
(
"
security.warn_entering_weak
"
,
false
);
user_pref
(
"
security.warn_entering_weak.show_once
"
,
false
);
user_pref
(
"
security.warn_leaving_secure
"
,
false
);
user_pref
(
"
security.warn_leaving_secure.show_once
"
,
false
);
user_pref
(
"
security.warn_viewing_mixed
"
,
false
);
user_pref
(
"
security.warn_viewing_mixed.show_once
"
,
false
);
// Disable "do you want to remember this password?"
user_pref
(
"
signon.rememberSignons
"
,
false
);
// increase the timeout before warning of unresponsive script
user_pref
(
"
dom.max_script_run_time
"
,
120
);
// this is required to upload files
// user_pref("capability.principal.codebase.p1.granted", "UniversalFileRead");
// user_pref("signed.applets.codebase_principal_support", true);
// user_pref("capability.principal.codebase.p1.id", "http://");
// user_pref("capability.principal.codebase.p1.subjectName", "");
user_pref
(
"
browser.link.open_external
"
,
3
);
user_pref
(
"
browser.link.open_newwindow
"
,
3
);
// disables the request to send performance data from displaying
user_pref
(
"
toolkit.telemetry.prompted
"
,
2
);
user_pref
(
"
toolkit.telemetry.rejected
"
,
true
);
user_pref
(
"
browser.migration.version
"
,
5
);
user_pref
(
"
extensions.SelectionUI
"
,
true
);
user_pref
(
"
network.cookie.prefsMigrated
"
,
true
);
user_pref
(
"
browser.bookmarks.restore_default_bookmarks
"
,
false
);
user_pref
(
"
browser.places.smartBookmarksVersion
"
,
2
);
user_pref
(
"
privacy.sanitize.migrateFx3Prefs
"
,
true
);
slapos/recipe/seleniumrunner/__init__.py
View file @
fd11c057
...
@@ -29,79 +29,19 @@ import os
...
@@ -29,79 +29,19 @@ import os
import
sys
import
sys
import
zc.buildout
import
zc.buildout
from
slapos.recipe.librecipe
import
BaseSlapRecipe
from
slapos.recipe.librecipe
import
BaseSlapRecipe
from
slapos.recipe.librecipe
import
GenericBaseRecipe
class
Recipe
(
BaseSlapRecipe
):
class
Recipe
(
GenericBaseRecipe
):
def
_install
(
self
):
def
install
(
self
):
"""Set the connection dictionnary for the computer partition and create a list
of paths to the different wrappers."""
self
.
path_list
=
[]
self
.
requirements
,
self
.
ws
=
self
.
egg
.
working_set
()
self
.
installTestrunner
(
self
.
getDisplay
())
runner
=
self
.
createPythonScript
(
self
.
linkBinary
()
self
.
options
[
'runner-path'
],
__name__
+
'.testrunner.run'
,
arguments
=
[
self
.
options
[
'suite-url'
],
self
.
options
[
'report-url'
],
self
.
options
[
'report-project'
],
self
.
options
[
'browser'
],
])
return
self
.
path_list
return
[
runner
]
def
getDisplay
(
self
):
"""Generate display id for the instance."""
display_list
=
[
":%s"
%
i
for
i
in
range
(
123
,
144
)]
for
display_try
in
display_list
:
lock_filepath
=
'/tmp/.X%s-lock'
%
display_try
.
replace
(
":"
,
""
)
if
not
os
.
path
.
exists
(
lock_filepath
):
display
=
display_try
break
return
display
def
installTestrunner
(
self
,
display
):
"""Instanciate a wrapper for the browser and the test reports."""
arguments
=
dict
(
xvfb_binary
=
self
.
options
[
'xvfb_binary'
],
display
=
display
,
suite_name
=
self
.
parameter_dict
[
'suite_name'
],
base_url
=
self
.
parameter_dict
[
'url'
],
browser_argument_list
=
[],
user
=
self
.
parameter_dict
[
'user'
],
password
=
self
.
parameter_dict
[
'password'
],
project
=
self
.
parameter_dict
[
'project'
],
test_report_instance_url
=
\
self
.
parameter_dict
[
'test_report_instance_url'
],
etc_directory
=
self
.
etc_directory
)
# Check wanted browser XXX-Cedric not yet used but can be useful
#if self.parameter_dict.get('browser', None) is None:
arguments
[
'browser_binary'
]
=
self
.
options
[
'firefox_binary'
]
#elif self.parameter_dict['browser'].strip().lowercase() == 'chrome' or
# self.parameter_dict['browser'].strip().lowercase() == 'chromium':
# arguments['browser_binary'] = self.options['chromium_binary']
# arguments['browser_argument_list'].extend['--ignore-certificate-errors',
# option_translate = '--disable-translate',
# option_security = '--disable-web-security']
#elif self.parameter_dict['browser'].strip().lowercase() == 'firefox':
# arguments['browser_binary'] = self.options['firefox_binary']
self
.
path_list
.
extend
(
zc
.
buildout
.
easy_install
.
scripts
([(
'testrunner'
,
__name__
+
'.testrunner'
,
'run'
)],
self
.
ws
,
sys
.
executable
,
self
.
wrapper_directory
,
arguments
=
[
arguments
]))
def
linkBinary
(
self
):
"""Links binaries to instance's bin directory for easier exposal"""
for
linkline
in
self
.
options
.
get
(
'link_binary_list'
,
''
).
splitlines
():
if
not
linkline
:
continue
target
=
linkline
.
split
()
if
len
(
target
)
==
1
:
target
=
target
[
0
]
path
,
linkname
=
os
.
path
.
split
(
target
)
else
:
linkname
=
target
[
1
]
target
=
target
[
0
]
link
=
os
.
path
.
join
(
self
.
bin_directory
,
linkname
)
if
os
.
path
.
lexists
(
link
):
if
not
os
.
path
.
islink
(
link
):
raise
zc
.
buildout
.
UserError
(
'Target link already %r exists but it is not link'
%
link
)
os
.
unlink
(
link
)
os
.
symlink
(
target
,
link
)
self
.
logger
.
debug
(
'Created link %r -> %r'
%
(
link
,
target
))
self
.
path_list
.
append
(
link
)
slapos/recipe/seleniumrunner/testrunner.py
View file @
fd11c057
...
@@ -27,14 +27,30 @@
...
@@ -27,14 +27,30 @@
from
datetime
import
datetime
from
datetime
import
datetime
from
erp5functionaltestreporthandler
import
ERP5TestReportHandler
from
erp5functionaltestreporthandler
import
ERP5TestReportHandler
from
ERP5TypeFunctionalTestCase
import
Xvfb
,
Firefox
,
TimeoutError
from
ERP5TypeFunctionalTestCase
import
TimeoutError
from
time
import
sleep
from
time
import
sleep
import
time
import
time
import
os
import
os
import
urllib2
import
urllib2
import
urlparse
from
subprocess
import
Popen
,
PIPE
import
signal
def
run
(
args
):
def
run
(
args
):
config
=
args
[
0
]
suite_url
=
args
[
0
]
report_url
=
args
[
1
]
project
=
args
[
2
]
browser_binary
=
args
[
3
]
suite_parsed
=
urlparse
.
urlparse
(
suite_url
)
config
=
{
'suite_name'
:
suite_parsed
.
path
.
split
(
'/'
)[
-
1
],
'base_url'
:
"%s://%s%s"
%
(
suite_parsed
.
scheme
,
suite_parsed
.
hostname
,
'/'
.
join
(
suite_parsed
.
path
.
split
(
'/'
)[:
-
1
])),
'user'
:
suite_parsed
.
username
,
'password'
:
suite_parsed
.
password
,
}
test_url
=
assembleTestUrl
(
config
[
'base_url'
],
config
[
'suite_name'
],
test_url
=
assembleTestUrl
(
config
[
'base_url'
],
config
[
'suite_name'
],
config
[
'user'
],
config
[
'password'
])
config
[
'user'
],
config
[
'password'
])
...
@@ -43,20 +59,17 @@ def run(args):
...
@@ -43,20 +59,17 @@ def run(args):
timeout
=
2.0
*
60
*
60
timeout
=
2.0
*
60
*
60
while
True
:
while
True
:
erp5_report
=
ERP5TestReportHandler
(
config
[
'test_report_instance_url'
]
,
erp5_report
=
ERP5TestReportHandler
(
report_url
,
config
[
'project'
]
+
'@'
+
config
[
'suite_name'
])
project
+
'@'
+
config
[
'suite_name'
])
try
:
try
:
os
.
environ
[
'DISPLAY'
]
=
config
[
'display'
]
xvfb
=
Xvfb
(
config
[
'etc_directory'
],
config
[
'xvfb_binary'
])
profile_dir
=
os
.
path
.
join
(
config
[
'etc_directory'
],
'profile'
)
# XXX-Cedric : change Firefox prefs.js generation so that it can take a
# list of websites supposed to be reached instead of config['base_url']
browser
=
Firefox
(
profile_dir
,
config
[
'base_url'
],
config
[
'browser_binary'
])
try
:
try
:
start
=
time
.
time
()
start
=
time
.
time
()
xvfb
.
run
()
print
(
"Running test on: %s"
%
test_url
)
profile_dir
=
os
.
path
.
join
(
config
[
'etc_directory'
],
'profile'
)
process
=
Popen
(
'%s "%s"'
%
(
browser_binary
,
test_url
),
browser
.
run
(
test_url
,
xvfb
.
display
)
stdout
=
PIPE
,
stderr
=
PIPE
,
shell
=
True
,
close_fds
=
True
)
erp5_report
.
reportStart
()
erp5_report
.
reportStart
()
while
not
isTestFinished
(
config
[
'base_url'
]):
while
not
isTestFinished
(
config
[
'base_url'
]):
time
.
sleep
(
10
)
time
.
sleep
(
10
)
...
@@ -66,8 +79,8 @@ def run(args):
...
@@ -66,8 +79,8 @@ def run(args):
except
TimeoutError
:
except
TimeoutError
:
continue
continue
finally
:
finally
:
browser
.
quit
()
if
process
.
pid
:
xvfb
.
quit
(
)
os
.
kill
(
process
.
pid
,
signal
.
SIGTERM
)
print
(
"Test has finished and Firefox has been killed."
)
print
(
"Test has finished and Firefox has been killed."
)
erp5_report
.
reportFinished
(
getStatus
(
config
[
'base_url'
]).
encode
(
"utf-8"
,
erp5_report
.
reportFinished
(
getStatus
(
config
[
'base_url'
]).
encode
(
"utf-8"
,
...
@@ -135,4 +148,4 @@ def assembleTestUrl(base_url, suite_name, user, password):
...
@@ -135,4 +148,4 @@ def assembleTestUrl(base_url, suite_name, user, password):
test_url
=
"%s/%s/core/TestRunner.html?test=../test_suite_html&"
\
test_url
=
"%s/%s/core/TestRunner.html?test=../test_suite_html&"
\
"resultsUrl=%s/postResults&auto=on&__ac_name=%s&__ac_password=%s"
%
(
"resultsUrl=%s/postResults&auto=on&__ac_name=%s&__ac_password=%s"
%
(
base_url
,
suite_name
,
base_url
,
user
,
password
)
base_url
,
suite_name
,
base_url
,
user
,
password
)
return
test_url
return
test_url
\ No newline at end of file
slapos/recipe/xvfb/__init__.py
0 → 100644
View file @
fd11c057
##############################################################################
#
# Copyright (c) 2012 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#############################################################################
from
slapos.recipe.librecipe
import
GenericBaseRecipe
class
Recipe
(
GenericBaseRecipe
):
def
install
(
self
):
config
=
{
'xvfb_binary'
:
self
.
options
[
'xvfb-path'
],
'shell_path'
:
self
.
options
[
'shell-path'
],
'fbdir_path'
:
self
.
options
[
'fbdir-path'
],
'tmp_path'
:
self
.
options
[
'tmp-path'
],
}
xvfb_path
=
self
.
createExecutable
(
self
.
options
[
'runner-path'
],
self
.
substituteTemplate
(
self
.
getTemplateFilename
(
'xvfb_run.in'
),
config
))
result
=
[
xvfb_path
]
# Allow to take screenshot if needed
if
(
'xwd-path'
in
self
.
options
)
and
(
'xwd-hook-path'
in
self
.
options
):
config
[
'xwd_binary'
]
=
self
.
options
[
'xwd-path'
]
result
.
append
(
self
.
createExecutable
(
self
.
options
[
'xwd-hook-path'
],
self
.
substituteTemplate
(
self
.
getTemplateFilename
(
'xwd_run.in'
),
config
)))
return
result
slapos/recipe/xvfb/template/xvfb_run.in
0 → 100644
View file @
fd11c057
#!%(shell_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
export TMPDIR=%(tmp_path)s
exec %(xvfb_binary)s -screen 0 1024x768x24 -fbdir %(fbdir_path)s
slapos/recipe/xvfb/template/xwd_run.in
0 → 100644
View file @
fd11c057
#!%(shell_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
export DISPLAY=:0
export TMPDIR=%(tmp_path)s
exec %(xwd_binary)s -root -out $1
software/seleniumrunner/instance-selenium.cfg
0 → 100644
View file @
fd11c057
[buildout]
parts =
selenium-instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[selenium-instance]
recipe = slapos.cookbook:seleniumrunner
runner-path = $${basedirectory:services}/selenium-runner
browser = $${firefox-instance:runner-path}
suite-url = $${slap-parameter:suite-url}
report-url = $${slap-parameter:report-url}
report-project = $${slap-parameter:report-project}
[firefox-instance]
recipe = slapos.cookbook:firefox
runner-path = $${rootdirectory:bin}/firefox-sandboxed
firefox-path = ${firefox:location}/firefox-slapos
prefsjs-path = $${rootdirectory:etc}/prefs.js
shell-path = ${dash:location}/bin/dash
tmp-path = $${xvfb-instance:tmp-path}
[xvfb-instance]
recipe = slapos.cookbook:xvfb
runner-path = $${basedirectory:services}/xvfb
xvfb-path = ${xserver:location}/bin/Xvfb
fbdir-path = $${basedirectory:framebuffer}
tmp-path = $${basedirectory:run}
shell-path = ${dash:location}/bin/dash
xwd-path = ${xwd:location}/bin/xwd
xwd-hook-path = $${rootdirectory:bin}/xwd
[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
var = $${buildout:directory}/var
srv = $${buildout:directory}/srv
bin = $${buildout:directory}/bin
[basedirectory]
recipe = slapos.cookbook:mkdirectory
services = $${rootdirectory:etc}/run
run = $${rootdirectory:var}/run
framebuffer = $${rootdirectory:srv}/framebuffer
software/seleniumrunner/instance.cfg
View file @
fd11c057
[buildout]
[buildout]
parts =
parts =
s
eleniuminstanc
e
s
witch-softwaretyp
e
eggs-directory = ${buildout:eggs-directory}
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[seleniuminstance]
[switch-softwaretype]
recipe = ${instance-recipe:egg}:${instance-recipe:module}
recipe = slapos.cookbook:softwaretype
xvfb_binary = ${xserver:location}/bin/Xvfb
default = ${template-selenium:output}
firefox_binary = ${firefox:location}/firefox-slapos
\ No newline at end of file
[slap-connection]
# part to migrate to new - separated words
computer-id = $${slap_connection:computer_id}
partition-id = $${slap_connection:partition_id}
server-url = $${slap_connection:server_url}
software-release-url = $${slap_connection:software_release_url}
key-file = $${slap_connection:key_file}
cert-file = $${slap_connection:cert_file}
software/seleniumrunner/software.cfg
View file @
fd11c057
...
@@ -6,8 +6,11 @@ extends =
...
@@ -6,8 +6,11 @@ extends =
../../component/lxml-python/buildout.cfg
../../component/lxml-python/buildout.cfg
../../component/python-2.7/buildout.cfg
../../component/python-2.7/buildout.cfg
../../component/firefox/buildout.cfg
../../component/firefox/buildout.cfg
../../component/dash/buildout.cfg
../../stack/shacache-client.cfg
../../stack/shacache-client.cfg
# develop += /opt/slapdev
versions = versions
versions = versions
find-links +=
find-links +=
...
@@ -19,6 +22,7 @@ parts =
...
@@ -19,6 +22,7 @@ parts =
instance-recipe-egg
instance-recipe-egg
xserver
xserver
firefox
firefox
xwd
versions = versions
versions = versions
...
@@ -43,10 +47,101 @@ eggs =
...
@@ -43,10 +47,101 @@ eggs =
# Default template for the instance.
# Default template for the instance.
recipe = slapos.recipe.template
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
url = ${:_profile_base_location_}/instance.cfg
md5sum =
5fc198144831525a196d7394e4b15f80
md5sum =
c4ac5de141ae6a64848309af03e51d88
output = ${buildout:directory}/template.cfg
output = ${buildout:directory}/template.cfg
mode = 0644
mode = 0644
[template-selenium]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-selenium.cfg
md5sum = 8be91f4515decef0f8af5910e43e0e52
output = ${buildout:directory}/template-selenium.cfg
mode = 0644
[versions]
[versions]
# Use SlapOS patched zc.buildout
# Use SlapOS patched zc.buildout
zc.buildout = 1.5.3-dev-SlapOS-010
zc.buildout = 1.6.0-dev-SlapOS-004
Jinja2 = 2.6
Werkzeug = 0.8.3
buildout-versions = 1.7
hexagonit.recipe.cmmi = 1.5.0
meld3 = 0.6.8
slapos.cookbook = 0.46
slapos.recipe.build = 0.7
slapos.recipe.template = 2.2
# Required by:
# slapos.core==0.23
Flask = 0.8
# Required by:
# slapos.cookbook==0.42
PyXML = 0.8.4
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.42
inotifyx = 0.2.0
# Required by:
# slapos.cookbook==0.42
# slapos.core==0.23
# xml-marshaller==0.9.7
lxml = 2.3.4
# Required by:
# slapos.cookbook==0.42
netaddr = 0.7.6
# Required by:
# slapos.core==0.23
netifaces = 0.8
# Required by:
# slapos.cookbook==0.42
# slapos.core==0.23
# zc.buildout==1.5.3-dev-SlapOS-010
# zc.recipe.egg==1.3.2
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.cookbook==0.42
slapos.core = 0.23
# Required by:
# slapos.core==0.23
supervisor = 3.0a12
# Required by:
# slapos.cookbook==0.42
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.42
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.23
zope.interface = 3.8.0
[networkcache]
# signature certificates of the following uploaders.
# Romain Courteaud
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB4DCCAUkCADANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJGUjEZMBcGA1UE
CBMQRGVmYXVsdCBQcm92aW5jZTEPMA0GA1UEChMGTmV4ZWRpMB4XDTExMDkxNTA5
MDAwMloXDTEyMDkxNTA5MDAwMlowOTELMAkGA1UEBhMCRlIxGTAXBgNVBAgTEERl
ZmF1bHQgUHJvdmluY2UxDzANBgNVBAoTBk5leGVkaTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEApYZv6OstoqNzxG1KI6iE5U4Ts2Xx9lgLeUGAMyfJLyMmRLhw
boKOyJ9Xke4dncoBAyNPokUR6iWOcnPHtMvNOsBFZ2f7VA28em3+E1JRYdeNUEtX
Z0s3HjcouaNAnPfjFTXHYj4um1wOw2cURSPuU5dpzKBbV+/QCb5DLheynisCAwEA
ATANBgkqhkiG9w0BAQsFAAOBgQBCZLbTVdrw3RZlVVMFezSHrhBYKAukTwZrNmJX
mHqi2tN8tNo6FX+wmxUUAf3e8R2Ymbdbn2bfbPpcKQ2fG7PuKGvhwMG3BlF9paEC
q7jdfWO18Zp/BG7tagz0jmmC4y/8akzHsVlruo2+2du2freE8dK746uoMlXlP93g
QUUGLQ==
-----END CERTIFICATE-----
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