Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
slapos.core
Commits
06006524
Commit
06006524
authored
May 30, 2011
by
Łukasz Nowak
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Imported branch rest from
https://gitorious.org/slapos/slapos-tool-proxy
parent
9c399c40
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
62 deletions
+178
-62
slapos/proxy/views.py
slapos/proxy/views.py
+178
-62
No files found.
slapos/proxy/views.py
View file @
06006524
from
flask
import
g
,
Flask
,
request
,
abort
from
flask
import
g
,
Flask
,
request
,
abort
,
json
import
xml_marshaller
import
xml_marshaller.xml_marshaller
from
slapos.slap.slap
import
Computer
,
ComputerPartition
,
SoftwareRelease
from
lxml
import
etree
from
lxml
import
etree
from
slapos.slap.slap
import
Computer
,
ComputerPartition
,
SoftwareRelease
,
SoftwareInstance
from
lxml.etree
import
XMLSyntaxError
import
sqlite3
import
sqlite3
from
simplejson.decoder
import
JSONDecodeError
app
=
Flask
(
__name__
)
app
=
Flask
(
__name__
)
DB_VERSION
=
app
.
open_resource
(
'schema.sql'
).
readline
().
strip
().
split
(
':'
)[
1
]
DB_VERSION
=
app
.
open_resource
(
'schema.sql'
).
readline
().
strip
().
split
(
':'
)[
1
]
...
@@ -10,6 +12,7 @@ DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1]
...
@@ -10,6 +12,7 @@ DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1]
class
UnauthorizedError
(
Exception
):
class
UnauthorizedError
(
Exception
):
pass
pass
#Deprecated
def
xml2dict
(
xml
):
def
xml2dict
(
xml
):
result_dict
=
{}
result_dict
=
{}
if
xml
is
not
None
and
xml
!=
''
:
if
xml
is
not
None
and
xml
!=
''
:
...
@@ -25,6 +28,7 @@ def xml2dict(xml):
...
@@ -25,6 +28,7 @@ def xml2dict(xml):
result_dict
[
key
]
=
value
result_dict
[
key
]
=
value
return
result_dict
return
result_dict
#Deprecated
def
dict2xml
(
dictionnary
):
def
dict2xml
(
dictionnary
):
instance
=
etree
.
Element
(
'instance'
)
instance
=
etree
.
Element
(
'instance'
)
for
parameter_id
,
parameter_value
in
dictionnary
.
iteritems
():
for
parameter_id
,
parameter_value
in
dictionnary
.
iteritems
():
...
@@ -35,7 +39,8 @@ def dict2xml(dictionnary):
...
@@ -35,7 +39,8 @@ def dict2xml(dictionnary):
return
etree
.
tostring
(
instance
,
pretty_print
=
True
,
return
etree
.
tostring
(
instance
,
pretty_print
=
True
,
xml_declaration
=
True
,
encoding
=
'utf-8'
)
xml_declaration
=
True
,
encoding
=
'utf-8'
)
def
partitiondict2partition
(
partition
):
#Deprecated
def
partitiondict2partitionXML
(
partition
):
slap_partition
=
ComputerPartition
(
app
.
config
[
'computer_id'
],
slap_partition
=
ComputerPartition
(
app
.
config
[
'computer_id'
],
partition
[
'reference'
])
partition
[
'reference'
])
slap_partition
.
_requested_state
=
'started'
slap_partition
.
_requested_state
=
'started'
...
@@ -43,7 +48,11 @@ def partitiondict2partition(partition):
...
@@ -43,7 +48,11 @@ def partitiondict2partition(partition):
slap_partition
.
_need_modification
=
1
slap_partition
.
_need_modification
=
1
else
:
else
:
slap_partition
.
_need_modification
=
0
slap_partition
.
_need_modification
=
0
try
:
slap_partition
.
_parameter_dict
=
xml2dict
(
partition
[
'xml'
])
slap_partition
.
_parameter_dict
=
xml2dict
(
partition
[
'xml'
])
except
XMLSyntaxError
:
# Maybe it was encoded in json
slap_partition
.
_parameter_dict
=
json
.
loads
(
partition
[
'xml'
])
address_list
=
[]
address_list
=
[]
for
address
in
execute_db
(
'partition_network'
,
'SELECT * FROM %s WHERE partition_reference=?'
,
[
partition
[
'reference'
]]):
for
address
in
execute_db
(
'partition_network'
,
'SELECT * FROM %s WHERE partition_reference=?'
,
[
partition
[
'reference'
]]):
address_list
.
append
((
address
[
'reference'
],
address
[
'address'
]))
address_list
.
append
((
address
[
'reference'
],
address
[
'address'
]))
...
@@ -55,6 +64,86 @@ def partitiondict2partition(partition):
...
@@ -55,6 +64,86 @@ def partitiondict2partition(partition):
computer_guid
=
app
.
config
[
'computer_id'
])
computer_guid
=
app
.
config
[
'computer_id'
])
return
slap_partition
return
slap_partition
#Deprecated. Only used for current version of slapgrid
@
app
.
route
(
'/registerComputerPartition'
,
methods
=
[
'GET'
])
def
registerComputerPartitionXml
():
computer_reference
=
request
.
args
[
'computer_reference'
]
computer_partition_reference
=
request
.
args
[
'computer_partition_reference'
]
if
app
.
config
[
'computer_id'
]
==
computer_reference
:
partition
=
execute_db
(
'partition'
,
'SELECT * FROM %s WHERE reference=?'
,
[
computer_partition_reference
.
encode
()],
one
=
True
)
if
partition
is
None
:
raise
UnauthorizedError
return
xml_marshaller
.
xml_marshaller
.
dumps
(
partitiondict2partitionXML
(
partition
))
else
:
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
app
.
config
[
'computer_id'
]
#Deprecated. Only used for current version of slapgrid
@
app
.
route
(
'/getComputerInformation'
,
methods
=
[
'GET'
])
def
getComputerInformationXml
():
computer_id
=
request
.
args
[
'computer_id'
]
if
app
.
config
[
'computer_id'
]
==
computer_id
:
slap_computer
=
Computer
(
computer_id
)
slap_computer
.
_software_release_list
=
[]
for
sr
in
execute_db
(
'software'
,
'select * from %s'
):
slap_computer
.
_software_release_list
.
append
(
SoftwareRelease
(
software_release
=
sr
[
'url'
],
computer_guid
=
computer_id
))
slap_computer
.
_computer_partition_list
=
[]
for
partition
in
execute_db
(
'partition'
,
'SELECT * FROM %s'
):
slap_computer
.
_computer_partition_list
.
append
(
partitiondict2partitionXML
(
partition
))
return
xml_marshaller
.
xml_marshaller
.
dumps
(
slap_computer
)
else
:
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
app
.
config
[
'computer_id'
]
#Deprecated. Only used for current version of slapgrid
@
app
.
route
(
'/setComputerPartitionConnectionXml'
,
methods
=
[
'POST'
])
def
setComputerPartitionConnectionXml
():
computer_id
=
request
.
form
[
'computer_id'
]
computer_partition_id
=
request
.
form
[
'computer_partition_id'
]
connection_xml
=
request
.
form
[
'connection_xml'
]
connection_dict
=
xml_marshaller
.
xml_marshaller
.
loads
(
connection_xml
.
encode
())
connection_xml
=
dict2xml
(
connection_dict
)
query
=
'UPDATE %s SET connection_xml=? WHERE reference=?'
argument_list
=
[
connection_xml
,
computer_partition_id
.
encode
()]
execute_db
(
'partition'
,
query
,
argument_list
)
return
'done'
def
partitiondict2partition
(
partition
):
# XXX-Cedric : change function name, as it does no longer create a
# Partition instance, but rather create a dict ready to be sent in json
slap_partition
=
dict
(
computer_id
=
app
.
config
[
'computer_id'
],
computer_partition_id
=
partition
[
'reference'
],
requested_state
=
'started'
,
partition_reference
=
partition
[
'partition_reference'
])
if
partition
[
'software_release'
]:
slap_partition
[
'need_modification'
]
=
1
else
:
slap_partition
[
'need_modification'
]
=
0
# XXX-Cedric : do we have to load a json into dict? It will be changed back to json anyway.
# XXX-Cedric : change from partition['xml'] to partition['json']
parameter_dict
=
dict
()
if
partition
[
'xml'
]:
parameter_dict
=
json
.
loads
(
partition
[
'xml'
])
slap_partition
[
'parameter_dict'
]
=
parameter_dict
address_list
=
[]
#XXX-Cedric : I do not understand the query. It is unclear what is partition['reference'], is it computer_partition_id or partition_reference?
for
address
in
execute_db
(
'partition_network'
,
'SELECT * FROM %s WHERE partition_reference=?'
,
[
partition
[
'reference'
]]):
address_list
.
append
((
address
[
'reference'
],
address
[
'address'
]))
slap_partition
[
'parameter_dict'
][
'ip_list'
]
=
address_list
slap_partition
[
'parameter_dict'
][
'software_type'
]
=
partition
[
'software_type'
]
# XXX-Cedric: same here
connection_dict
=
None
if
partition
[
'connection_xml'
]:
connection_dict
=
xml2dict
(
partition
[
'connection_xml'
])
slap_partition
[
'connection_dict'
]
=
connection_dict
slap_partition
[
'software_release'
]
=
partition
[
'software_release'
]
return
slap_partition
def
execute_db
(
table
,
query
,
args
=
(),
one
=
False
):
def
execute_db
(
table
,
query
,
args
=
(),
one
=
False
):
try
:
try
:
cur
=
g
.
db
.
execute
(
query
%
(
table
+
DB_VERSION
,),
args
)
cur
=
g
.
db
.
execute
(
query
%
(
table
+
DB_VERSION
,),
args
)
...
@@ -83,34 +172,29 @@ def after_request(response):
...
@@ -83,34 +172,29 @@ def after_request(response):
g
.
db
.
close
()
g
.
db
.
close
()
return
response
return
response
@
app
.
route
(
'/
getComputerInformation
'
,
methods
=
[
'GET'
])
@
app
.
route
(
'/
<computer_id>
'
,
methods
=
[
'GET'
])
def
getComputerInformation
():
def
getComputerInformation
(
computer_id
):
computer_id
=
request
.
args
[
'computer_id'
]
"""Returns information about computer"""
if
app
.
config
[
'computer_id'
]
==
computer_id
:
if
app
.
config
[
'computer_id'
]
==
computer_id
:
slap_computer
=
Computer
(
computer_id
)
slap_computer
=
dict
(
computer_id
=
computer_id
,
slap_computer
.
_software_release_list
=
[]
software_release_list
=
[],
computer_partition_list
=
[])
for
sr
in
execute_db
(
'software'
,
'select * from %s'
):
for
sr
in
execute_db
(
'software'
,
'select * from %s'
):
slap_computer
.
_software_release_list
.
append
(
SoftwareRelease
(
slap_computer
[
'software_release_list'
].
append
(
dict
(
software_release
=
sr
[
'url'
],
computer_guid
=
computer_id
))
software_release
=
sr
[
'url'
],
computer_guid
=
computer_id
))
slap_computer
.
_computer_partition_list
=
[]
for
partition
in
execute_db
(
'partition'
,
'SELECT * FROM %s'
):
for
partition
in
execute_db
(
'partition'
,
'SELECT * FROM %s'
):
slap_computer
.
_computer_partition_list
.
append
(
partitiondict2partition
(
slap_computer
[
'computer_partition_list'
].
append
(
partition
))
partitiondict2partition
(
partition
))
return
xml_marshaller
.
xml_marshaller
.
dumps
(
slap_computer
)
return
json
.
dumps
(
slap_computer
)
else
:
else
:
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
app
.
config
[
'computer_id'
]
app
.
config
[
'computer_id'
]
@
app
.
route
(
'/setComputerPartitionConnectionXml'
,
methods
=
[
'POST'
])
@
app
.
route
(
'/<computer_id>/partition/<computer_partition_id>'
,
methods
=
[
'POST'
])
def
setComputerPartitionConnectionXml
():
def
setComputerPartitionConnectionJson
(
computer_id
,
computer_partition_id
):
computer_id
=
request
.
form
[
'computer_id'
]
# XXX-Cedric : change connection_xml to connection_json in sql
computer_partition_id
=
request
.
form
[
'computer_partition_id'
]
connection_xml
=
request
.
form
[
'connection_xml'
]
connection_dict
=
xml_marshaller
.
xml_marshaller
.
loads
(
connection_xml
.
encode
())
connection_xml
=
dict2xml
(
connection_dict
)
query
=
'UPDATE %s SET connection_xml=? WHERE reference=?'
query
=
'UPDATE %s SET connection_xml=? WHERE reference=?'
argument_list
=
[
connection_xml
,
computer_partition_id
.
encode
()]
argument_list
=
[
request
.
json
,
computer_partition_id
.
encode
()]
execute_db
(
'partition'
,
query
,
argument_list
)
execute_db
(
'partition'
,
query
,
argument_list
)
return
'done'
return
'done'
...
@@ -165,21 +249,29 @@ def destroyedComputerPartition():
...
@@ -165,21 +249,29 @@ def destroyedComputerPartition():
computer_partition_id
=
request
.
form
[
'computer_partition_id'
]
computer_partition_id
=
request
.
form
[
'computer_partition_id'
]
return
'Ignored'
return
'Ignored'
@
app
.
route
(
'/requestComputerPartition'
,
methods
=
[
'POST'
])
#@app.route('/partition/<partition_reference>', methods=['PUT'])
def
requestComputerPartition
():
@
app
.
route
(
'/partition'
,
methods
=
[
'POST'
])
software_release
=
request
.
form
[
'software_release'
].
encode
()
def
requestComputerPartition
(
partition_reference
=
''
):
"""Request the creation of a computer partition"""
request_dict
=
request
.
json
software_release
=
request_dict
[
'software_release'
].
encode
()
# some supported parameters
# some supported parameters
software_type
=
request
.
form
.
get
(
'software_type'
,
'RootSoftwareInstance'
software_type
=
request_dict
.
get
(
'software_type'
,
'RootSoftwareInstance'
)
).
encode
()
if
(
software_type
is
None
):
partition_reference
=
request
.
form
.
get
(
'partition_reference'
,
''
).
encode
()
software_type
=
'RootSoftwareInstance'
partition_id
=
request
.
form
.
get
(
'computer_partition_id'
,
''
).
encode
()
software_type
=
software_type
.
encode
()
partition_parameter_kw
=
request
.
form
.
get
(
'partition_parameter_xml'
,
None
)
if
partition_reference
is
''
:
if
partition_parameter_kw
:
partition_reference
=
request_dict
.
get
(
'partition_reference'
,
''
).
encode
()
partition_parameter_kw
=
xml_marshaller
.
xml_marshaller
.
loads
(
partition_id
=
request_dict
.
get
(
'computer_partition_id'
,
''
)
partition_parameter_kw
.
encode
())
if
(
partition_id
is
None
):
else
:
partition_id
=
''
partition_parameter_kw
=
{}
partition_id
=
partition_id
.
encode
()
instance_xml
=
dict2xml
(
partition_parameter_kw
)
parameter_dict_kw
=
request_dict
.
get
(
'parameter_dict'
,
None
)
if
parameter_dict_kw
:
# In the future, parameter_dict will come either in xml or in json.
# We will check it with schema.
parameter_dict_kw
=
json
.
dumps
(
parameter_dict_kw
).
encode
()
instance_json
=
parameter_dict_kw
args
=
[]
args
=
[]
a
=
args
.
append
a
=
args
.
append
q
=
'SELECT * FROM %s WHERE software_release=?'
q
=
'SELECT * FROM %s WHERE software_release=?'
...
@@ -213,9 +305,10 @@ def requestComputerPartition():
...
@@ -213,9 +305,10 @@ def requestComputerPartition():
if
partition_id
:
if
partition_id
:
q
+=
' ,requested_by=?'
q
+=
' ,requested_by=?'
a
(
partition_id
)
a
(
partition_id
)
if
instance_xml
:
if
instance_json
:
# XXX-Cedric : change xml to sjon in sql
q
+=
' ,xml=?'
q
+=
' ,xml=?'
a
(
instance_
xml
)
a
(
instance_
json
)
q
+=
' WHERE reference=?'
q
+=
' WHERE reference=?'
a
(
partition
[
'reference'
].
encode
())
a
(
partition
[
'reference'
].
encode
())
execute_db
(
'partition'
,
q
,
args
)
execute_db
(
'partition'
,
q
,
args
)
...
@@ -225,25 +318,28 @@ def requestComputerPartition():
...
@@ -225,25 +318,28 @@ def requestComputerPartition():
address_list
=
[]
address_list
=
[]
for
address
in
execute_db
(
'partition_network'
,
'SELECT * FROM %s WHERE partition_reference=?'
,
[
partition
[
'reference'
]]):
for
address
in
execute_db
(
'partition_network'
,
'SELECT * FROM %s WHERE partition_reference=?'
,
[
partition
[
'reference'
]]):
address_list
.
append
((
address
[
'reference'
],
address
[
'address'
]))
address_list
.
append
((
address
[
'reference'
],
address
[
'address'
]))
return
xml_marshaller
.
xml_marshaller
.
dumps
(
SoftwareInstance
(
**
dict
(
return
json
.
dumps
(
dict
(
# XXX-Cedric : change xml to json in sql
# XXX-Cedric : change this to return something that looks like a computer partition
xml
=
partition
[
'xml'
],
xml
=
partition
[
'xml'
],
connection_xml
=
partition
[
'connection_xml'
],
connection_xml
=
partition
[
'connection_xml'
],
partition_reference
=
partition
[
'partition_reference'
],
slap_computer_id
=
app
.
config
[
'computer_id'
],
slap_computer_id
=
app
.
config
[
'computer_id'
],
slap_computer_partition_id
=
partition
[
'reference'
],
slap_computer_partition_id
=
partition
[
'reference'
],
slap_software_release_url
=
partition
[
'software_release'
],
slap_software_release_url
=
partition
[
'software_release'
],
slap_server_url
=
'slap_server_url'
,
slap_server_url
=
'slap_server_url'
,
s
lap_s
oftware_type
=
partition
[
'software_type'
],
software_type
=
partition
[
'software_type'
],
slave_id_list
=
[],
slave_id_list
=
[],
ip_list
=
address_list
ip_list
=
address_list
))
)
))
abort
(
408
)
abort
(
408
)
computer_id
=
request
.
form
.
get
(
'computer_id'
)
computer_id
=
request
.
form
.
get
(
'computer_id'
)
computer_partition_id
=
request
.
form
.
get
(
'computer_partition_id'
)
computer_partition_id
=
request
.
form
.
get
(
'computer_partition_id'
)
software_type
=
request
.
form
.
get
(
'software_type'
)
software_type
=
request
.
form
.
get
(
'software_type'
)
partition_reference
=
request
.
form
.
get
(
'partition_reference'
)
partition_reference
=
request
.
form
.
get
(
'partition_reference'
)
shared
_xml
=
request
.
form
.
get
(
'shared_xml
'
)
shared
=
request
.
form
.
get
(
'shared
'
)
par
tition_parameter_xml
=
request
.
form
.
get
(
'partition_parameter_xml
'
)
par
ameter_dict
=
request
.
form
.
get
(
'parameter_dict
'
)
filter_
xml
=
request
.
form
.
get
(
'filter_xml
'
)
filter_
json
=
request
.
form
.
get
(
'filter_json
'
)
raise
NotImplementedError
raise
NotImplementedError
@
app
.
route
(
'/useComputer'
,
methods
=
[
'POST'
])
@
app
.
route
(
'/useComputer'
,
methods
=
[
'POST'
])
...
@@ -275,25 +371,45 @@ def loadComputerConfigurationFromXML():
...
@@ -275,25 +371,45 @@ def loadComputerConfigurationFromXML():
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
app
.
config
[
'computer_id'
]
app
.
config
[
'computer_id'
]
@
app
.
route
(
'/registerComputerPartition'
,
methods
=
[
'GET'
])
#XXX-Cedric : We still use XML for formatting for now.
def
registerComputerPartition
():
#@app.route('/loadComputerConfiguration', methods=['POST'])
computer_reference
=
request
.
args
[
'computer_reference'
]
#def loadComputerConfigurationFromJson():
computer_partition_reference
=
request
.
args
[
'computer_partition_reference'
]
# json_document = request.form['json']
# computer_dict = json.loads(str(json_document))
# if app.config['computer_id'] == computer_dict['reference']:
# args = []
# a = args.append
# execute_db('computer', 'INSERT OR REPLACE INTO %s values(:address, :netmask)',
# computer_dict)
# for partition in computer_dict['partition_list']:
#
# execute_db('partition', 'INSERT OR IGNORE INTO %s (reference) values(:reference)', partition)
# execute_db('partition_network', 'DELETE FROM %s WHERE partition_reference = ?', [partition['reference']])
# for address in partition['address_list']:
# address['reference'] = partition['tap']['name']
# address['partition_reference'] = partition['reference']
# execute_db('partition_network', 'INSERT OR REPLACE INTO %s (reference, partition_reference, address, netmask) values(:reference, :partition_reference, :addr, :netmask)', address)
#
# return 'done'
# else:
# raise UnauthorizedError, "Only accept request for: %s" % \
# app.config['computer_id']
@
app
.
route
(
'/<computer_reference>/partition/<partition_reference>'
,
methods
=
[
'GET'
])
def
registerComputerPartition
(
computer_reference
,
partition_reference
):
if
app
.
config
[
'computer_id'
]
==
computer_reference
:
if
app
.
config
[
'computer_id'
]
==
computer_reference
:
partition
=
execute_db
(
'partition'
,
'SELECT * FROM %s WHERE reference=?'
,
partition
=
execute_db
(
'partition'
,
'SELECT * FROM %s WHERE reference=?'
,
[
computer_
partition_reference
.
encode
()],
one
=
True
)
[
partition_reference
.
encode
()],
one
=
True
)
if
partition
is
None
:
if
partition
is
None
:
raise
UnauthorizedError
raise
UnauthorizedError
return
xml_marshaller
.
xml_marshaller
.
dumps
(
return
json
.
dumps
(
partitiondict2partition
(
partition
))
partitiondict2partition
(
partition
))
else
:
else
:
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
raise
UnauthorizedError
,
"Only accept request for: %s"
%
\
app
.
config
[
'computer_id'
]
app
.
config
[
'computer_id'
]
@
app
.
route
(
'/supplySupply'
,
methods
=
[
'POST'
])
@
app
.
route
(
'/<computer_id>/software'
,
methods
=
[
'POST'
])
def
supplySupply
():
def
supplySupply
(
computer_id
):
url
=
request
.
form
[
'url'
]
url
=
request
.
json
[
'url'
]
computer_id
=
request
.
form
[
'computer_id'
]
if
app
.
config
[
'computer_id'
]
==
computer_id
:
if
app
.
config
[
'computer_id'
]
==
computer_id
:
execute_db
(
'software'
,
'INSERT OR REPLACE INTO %s VALUES(?)'
,
[
url
])
execute_db
(
'software'
,
'INSERT OR REPLACE INTO %s VALUES(?)'
,
[
url
])
else
:
else
:
...
...
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