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
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
Ivan Tyagov
slapos
Commits
02bb91c3
Commit
02bb91c3
authored
Aug 14, 2019
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Plain Diff
Update Release Candidate
parents
24d1d7cf
4f15f8a1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
128 additions
and
139 deletions
+128
-139
CHANGES.rst
CHANGES.rst
+7
-0
setup.py
setup.py
+1
-1
slapos/recipe/neoppod.py
slapos/recipe/neoppod.py
+6
-10
slapos/recipe/publish_early.py
slapos/recipe/publish_early.py
+63
-68
slapos/recipe/random.py
slapos/recipe/random.py
+46
-44
software/wendelin/software.cfg
software/wendelin/software.cfg
+2
-13
stack/slapos.cfg
stack/slapos.cfg
+3
-3
No files found.
CHANGES.rst
View file @
02bb91c3
Changes
=======
1.0.119 (2019-08-14)
--------------------
* publish_early: rework API
1.0.118 (2019-08-13)
--------------------
...
...
setup.py
View file @
02bb91c3
...
...
@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import
glob
import
os
version
=
'1.0.11
8
'
version
=
'1.0.11
9
'
name
=
'slapos.cookbook'
long_description
=
open
(
"README.rst"
).
read
()
+
"
\
n
"
+
\
open
(
"CHANGES.rst"
).
read
()
+
"
\
n
"
...
...
slapos/recipe/neoppod.py
View file @
02bb91c3
...
...
@@ -32,30 +32,26 @@ from .librecipe import GenericBaseRecipe
class
Cluster
(
object
):
def
__init__
(
self
,
buildout
,
name
,
options
):
self
.
buildout
=
buildout
self
.
options
=
options
def
publish_early
(
self
,
publish_dict
):
masters
=
publish_dict
.
setdefault
(
'masters'
,
''
)
masters
=
options
.
setdefault
(
'masters'
,
''
)
result_dict
=
{
'connection-admin'
:
[],
'connection-master'
:
[],
}
node_list
=
[]
for
node
in
sorted
(
self
.
options
[
'nodes'
].
split
()):
node
=
self
.
buildout
[
node
]
for
node
in
sorted
(
options
[
'nodes'
].
split
()):
node
=
buildout
[
node
]
node_list
.
append
(
node
)
for
k
,
v
in
result_dict
.
iteritems
():
x
=
node
[
k
]
if
x
:
v
.
append
(
x
)
publish_dict
[
'admins'
]
=
' '
.
join
(
result_dict
.
pop
(
'connection-admin'
))
options
[
'admins'
]
=
' '
.
join
(
result_dict
.
pop
(
'connection-admin'
))
x
=
' '
.
join
(
result_dict
.
pop
(
'connection-master'
))
if
masters
!=
x
:
publish_dict
[
'masters'
]
=
x
options
[
'masters'
]
=
x
for
node
in
node_list
:
node
[
'config-masters'
]
=
x
node
.
recipe
.
__init__
(
self
.
buildout
,
node
.
name
,
node
)
node
.
recipe
.
__init__
(
buildout
,
node
.
name
,
node
)
install
=
update
=
lambda
self
:
None
...
...
slapos/recipe/publish_early.py
View file @
02bb91c3
...
...
@@ -28,20 +28,14 @@
from
collections
import
defaultdict
from
.librecipe
import
unwrap
,
wrap
,
GenericSlapRecipe
def
patchOptions
(
options
,
override
):
def
get
(
option
,
*
args
,
**
kw
):
try
:
return
override
[
option
]
except
KeyError
:
return
options_get
(
option
,
*
args
,
**
kw
)
try
:
options_get
=
options
.
_get
except
AttributeError
:
options_get
=
options
.
get
options
.
get
=
get
else
:
options
.
_get
=
get
def
volatileOptions
(
options
,
volatile
):
def
copy
():
copy
=
options_copy
()
for
key
in
volatile
:
copy
.
pop
(
key
,
None
)
return
copy
options_copy
=
options
.
copy
options
.
copy
=
copy
class
Recipe
(
GenericSlapRecipe
):
"""
...
...
@@ -57,8 +51,6 @@ class Recipe(GenericSlapRecipe):
-init =
foo gen-foo:x
bar gen-bar:y
-update =
baz update-baz:z
bar = z
[gen-foo]
...
...
@@ -69,72 +61,74 @@ class Recipe(GenericSlapRecipe):
-extends = publish-early
...
${publish-early:foo} is initialized with the value of the published
parameter 'foo', or ${gen-foo:x} if it hasn't been published yet
(and in this case, it is published immediately as a way to save the value).
Just before the recipe of [gen-foo] is instantiated, 'x' is overridden with
the published value 'foo' if it exists. If its __init__ modifies 'x', the new
value is published. To prevent [gen-foo] from being accessed too early, 'x'
is then removed and the value can only be accessed with ${publish-early:foo}.
Generated values don't end up in the buildout installed file, which is good
if they're secret. Note however that buildout won't detect if values change
and it may only call update().
${publish-early:bar} is forced to 'z' (${gen-bar:y} ignored):
a line like 'bar = z' is usually rendered conditionally with Jinja2.
The '-update' option has the same syntax than '-init'. The recipes of the
specified sections must implement 'publish_early(publish_dict)':
- it is always called, just before early publishing
- publish_dict is a dict with already published values
- 'publish_early' can change published values by modifying publish_dict.
In the above example:
- publish_dict is {'z': ...}
- during the execution of 'publish_early', other sections can access the
value with ${update-baz:z}
- once [publish-early] is initialized, the value should be accessed with
${publish-early:bar} ([update-baz] does not have it if it's accessed
before [publish-early])
"""
def
__init__
(
self
,
buildout
,
name
,
options
):
GenericSlapRecipe
.
__init__
(
self
,
buildout
,
name
,
options
)
init
=
defaultdict
(
dict
)
update
=
defaultdict
(
dict
)
for
d
,
k
in
(
init
,
'-init'
),
(
update
,
'-update'
):
for
line
in
options
.
get
(
k
,
''
).
splitlines
():
if
line
:
k
,
v
=
line
.
split
()
if
k
not
in
options
:
section
,
v
=
v
.
split
(
':'
)
d
[
section
][
k
]
=
v
if
init
or
update
:
for
line
in
options
[
'-init'
].
splitlines
():
if
line
:
k
,
v
=
line
.
split
()
if
k
not
in
options
:
section
,
v
=
v
.
split
(
':'
)
init
[
section
][
k
]
=
v
if
init
:
self
.
slap
.
initializeConnection
(
self
.
server_url
,
self
.
key_file
,
self
.
cert_file
)
computer_partition
=
self
.
slap
.
registerComputerPartition
(
self
.
computer_id
,
self
.
computer_partition_id
)
published_dict
=
unwrap
(
computer_partition
.
getConnectionParameterDict
())
Options
=
buildout
.
Options
if
'Options'
in
buildout
.
__dict__
:
def
revertOptions
():
buildout
.
Options
=
Options
else
:
def
revertOptions
():
try
:
del
buildout
.
Options
except
AttributeError
:
pass
def
newOptions
(
buildout
,
section
,
data
):
assert
section
==
init_section
,
(
section
,
init_section
)
revertOptions
()
self
=
buildout
.
Options
(
buildout
,
section
,
data
)
self
.
update
(
override
)
return
self
publish
=
False
publish_dict
=
{}
for
section
,
init
in
init
.
iteritems
():
for
k
,
v
in
init
.
iteritems
():
try
:
publish_dict
[
k
]
=
published_dict
[
k
]
except
KeyError
:
publish_dict
[
k
]
=
buildout
[
section
][
v
]
try
:
for
init_section
,
init
in
init
.
iteritems
():
override
=
{}
for
k
,
v
in
init
.
iteritems
():
try
:
override
[
v
]
=
published_dict
[
k
]
except
KeyError
:
pass
buildout
.
Options
=
newOptions
init_section
=
buildout
[
init_section
]
assert
buildout
.
Options
is
Options
new
=
{}
for
k
,
v
in
init
.
iteritems
():
try
:
publish_dict
[
k
]
=
new
[
v
]
=
init_section
.
pop
(
v
)
except
KeyError
:
pass
if
new
!=
override
:
publish
=
True
for
section
,
update
in
update
.
iteritems
():
override
=
{}
for
k
,
v
in
update
.
iteritems
():
try
:
override
[
v
]
=
published_dict
[
k
]
except
KeyError
:
pass
section
=
buildout
[
section
]
patchOptions
(
section
,
override
)
old
=
override
.
copy
()
section
.
recipe
.
publish_early
(
override
)
if
override
!=
old
:
publish
=
True
for
k
,
v
in
update
.
iteritems
():
try
:
publish_dict
[
k
]
=
override
[
v
]
except
KeyError
:
pass
finally
:
revertOptions
()
if
publish
:
computer_partition
.
setConnectionDict
(
wrap
(
publish_dict
))
...
...
@@ -143,6 +137,7 @@ class Recipe(GenericSlapRecipe):
if
k
!=
'recipe'
and
not
k
.
startswith
(
'-'
)]
publish
+=
publish_dict
publish_dict
[
'-publish'
]
=
' '
.
join
(
publish
)
patchOptions
(
options
,
publish_dict
)
volatileOptions
(
options
,
list
(
publish_dict
))
options
.
update
(
publish_dict
)
install
=
update
=
lambda
self
:
None
slapos/recipe/random.py
View file @
02bb91c3
...
...
@@ -36,8 +36,8 @@ import errno
import
os
import
random
import
string
from
slapos.recipe.librecipe
import
GenericBaseRecipe
from
.librecipe
import
GenericBaseRecipe
from
.publish_early
import
volatileOptions
class
Integer
(
object
):
"""
...
...
@@ -54,7 +54,9 @@ class Integer(object):
Resulting integer.
"""
def
__init__
(
self
,
buildout
,
name
,
options
):
options
[
'value'
]
=
random
.
randint
(
int
(
options
[
'minimum'
]),
int
(
options
[
'maximum'
]))
if
'value'
not
in
options
:
options
[
'value'
]
=
random
.
randint
(
int
(
options
[
'minimum'
]),
int
(
options
[
'maximum'
]))
def
install
(
self
):
pass
...
...
@@ -65,10 +67,9 @@ class Time(object):
"""Generate a random time from a 24h time clock"""
def
__init__
(
self
,
buildout
,
name
,
options
):
self
.
name
=
name
self
.
buildout
=
buildout
self
.
options
=
options
self
.
options
[
'time'
]
=
"%d:%d"
%
(
random
.
randint
(
0
,
23
),
random
.
randint
(
0
,
59
))
if
'time'
not
in
options
:
options
[
'time'
]
=
"%u:%02u"
%
(
random
.
randint
(
0
,
23
),
random
.
randint
(
0
,
59
))
def
install
(
self
):
pass
...
...
@@ -76,26 +77,33 @@ class Time(object):
update
=
install
class
Mac
(
GenericBaseRecipe
):
class
Mac
(
object
):
def
__init__
(
self
,
buildout
,
name
,
options
):
if
os
.
path
.
exists
(
options
[
'storage-path'
]):
open_file
=
open
(
options
[
'storage-path'
],
'r'
)
options
[
'mac-address'
]
=
open_file
.
read
()
open_file
.
close
()
if
options
.
get
(
'mac-address'
,
''
)
==
''
:
# First octet has to represent a locally administered address
octet_list
=
[
254
]
+
[
random
.
randint
(
0x00
,
0xff
)
for
x
in
range
(
5
)]
options
[
'mac-address'
]
=
':'
.
join
([
'%02x'
%
x
for
x
in
octet_list
])
return
GenericBaseRecipe
.
__init__
(
self
,
buildout
,
name
,
options
)
self
.
storage_path
=
options
[
'storage-path'
]
mac
=
options
.
get
(
'mac-address'
)
if
not
mac
:
try
:
with
open
(
self
.
storage_path
)
as
f
:
mac
=
f
.
read
()
except
IOError
as
e
:
if
e
.
errno
!=
errno
.
ENOENT
:
raise
if
not
mac
:
# First octet has to represent a locally administered address
octet_list
=
[
254
]
+
[
random
.
randint
(
0x00
,
0xff
)
for
x
in
range
(
5
)]
mac
=
':'
.
join
([
'%02x'
%
x
for
x
in
octet_list
])
self
.
update
=
self
.
install
options
[
'mac-address'
]
=
mac
self
.
mac
=
mac
def
install
(
self
):
open_file
=
open
(
self
.
options
[
'storage-path'
],
'w'
)
open_file
.
write
(
self
.
options
[
'mac-address'
])
open_file
.
close
()
return
[
self
.
options
[
'storage-path'
]]
with
open
(
self
.
storage_path
,
'w'
)
as
f
:
f
.
write
(
self
.
mac
)
return
self
.
storage_path
def
update
(
self
):
pass
def
generatePassword
(
length
):
return
''
.
join
(
random
.
SystemRandom
().
sample
(
string
.
ascii_lowercase
,
length
))
...
...
@@ -130,30 +138,24 @@ class Password(object):
except
KeyError
:
self
.
storage_path
=
options
[
'storage-path'
]
=
os
.
path
.
join
(
buildout
[
'buildout'
][
'parts-directory'
],
name
)
passwd
=
None
if
self
.
storage_path
:
try
:
with
open
(
self
.
storage_path
)
as
f
:
passwd
=
f
.
read
().
strip
(
'
\
n
'
)
except
IOError
as
e
:
if
e
.
errno
!=
errno
.
ENOENT
:
raise
passwd
=
options
.
get
(
'passwd'
)
if
not
passwd
:
passwd
=
self
.
generatePassword
(
int
(
options
.
get
(
'bytes'
,
'8'
)))
self
.
update
=
self
.
install
self
.
passwd
=
passwd
if
self
.
storage_path
:
try
:
with
open
(
self
.
storage_path
)
as
f
:
passwd
=
f
.
read
().
strip
(
'
\
n
'
)
except
IOError
as
e
:
if
e
.
errno
!=
errno
.
ENOENT
:
raise
if
not
passwd
:
passwd
=
self
.
generatePassword
(
int
(
options
.
get
(
'bytes'
,
'8'
)))
self
.
update
=
self
.
install
options
[
'passwd'
]
=
passwd
# Password must not go into .installed file, for 2 reasons:
# security of course but also to prevent buildout to always reinstall.
def
get
(
option
,
*
args
,
**
kw
):
return
passwd
if
option
==
'passwd'
else
options_get
(
option
,
*
args
,
**
kw
)
try
:
options_get
=
options
.
_get
except
AttributeError
:
options_get
=
options
.
get
options
.
get
=
get
else
:
options
.
_get
=
get
# publish_early already does it, but this recipe may also be used alone.
volatileOptions
(
options
,
(
'passwd'
,))
self
.
passwd
=
passwd
generatePassword
=
staticmethod
(
generatePassword
)
...
...
@@ -179,4 +181,4 @@ class Password(object):
return
self
.
storage_path
def
update
(
self
):
return
()
pass
software/wendelin/software.cfg
View file @
02bb91c3
...
...
@@ -8,7 +8,6 @@ extends =
../../software/erp5/software.cfg
parts +=
wendelin
erp5-bin
scipy
msgpack-python
msgpack-numpy
...
...
@@ -61,14 +60,10 @@ initialization =
${testrunner:initialization}
[erp5_repository_list]
repository_id_list +=
wendelin
erp5-bin
repository_id_list += wendelin
[local-bt5-repository]
list +=
${wendelin:location}/bt5
${erp5-bin:location}/bt5
list += ${wendelin:location}/bt5
# Jupyter is by default enabled in Wendelin
[erp5-defaults]
...
...
@@ -80,12 +75,6 @@ git-executable = ${git:location}/bin/git
repository = https://lab.nexedi.com/nexedi/wendelin.git
branch = master
[erp5-bin]
recipe = slapos.recipe.build:gitclone
git-executable = ${git:location}/bin/git
repository = https://lab.nexedi.com/nexedi/erp5-bin.git
branch = master
[versions]
msgpack = 0.6.1
msgpack-numpy = 0.4.4.3
...
...
stack/slapos.cfg
View file @
02bb91c3
...
...
@@ -136,7 +136,7 @@ pyparsing = 2.2.0
pytz = 2016.10
requests = 2.13.0
six = 1.11.0
slapos.cookbook = 1.0.11
8
slapos.cookbook = 1.0.11
9
slapos.core = 1.4.26
slapos.extension.strip = 0.4
slapos.extension.shared = 1.0
...
...
@@ -195,7 +195,7 @@ enum34 = 1.1.6
# Required by:
# slapos.toolbox==0.94
erp5.util = 0.4.59
erp5.util = 0.4.59
.1
# Required by:
# slapos.toolbox==0.94
...
...
@@ -218,7 +218,7 @@ pyrsistent = 0.14.5
ipaddress = 1.0.18
# Required by:
# slapos.cookbook==1.0.11
8
# slapos.cookbook==1.0.11
9
jsonschema = 3.0.0a3
# Required by:
...
...
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