For example, I'd like to create a composed module as 'myprocessor':
xd> module compose myprocessor --definition "processor1 | processor2 | processor3".
In addition, I'd also like to make the number of processor1, processor2 and processor3 be 4:2:1 in the composed module and all the communication between them are in-process.
How can I achieve it? Can I specify it during creation using command like:
xd> module compose myprocessor --definition "processor1 --count=4| processor2 --count=2| processor3 --count=1"
or during deployment?
Thanks,
Simon
No; that's not possible. A composed module is a single module (a black box) with the component modules being hard-wired together.
But since you have "reducing" counts, simply set the count to 4 when using the composed module. What are you trying to achieve using fewer processor2/3 than 1 ?
Related
I am writing and implementing some MIB files. I want to implement a bunch of objects in a Base-MIB and reuse it in multiple projects. One way is to copy Base-MIB for each project and then import mibs of each project to corresponding Base-MIB (as examples in Cisco MIBs that CISCOWORKS-MIB imports ciscoworks from CISCO-SMI and use it as parent of MODULE-IDENTITY). In this way I should set a different parent to MODULE-IDENTITY of each copy of Base-MIB and having 2 different instance of Base-MIB.
But I want to do it in a reverse manner. It means importing a Base-MIB in mibs of each project and then use defined objects in Base-MIB as a sub-tree with different OIDs and different implementation specific to each project (So different values). But i have problem to assign different OIDs to objects inside Base-MIB. I want to use exactly the same Base-MIB instance for both projects.
Is there any syntax or rule to achieve this task?
regards.
Hi can anyone tell me the use of 'like' keyword in NED Language. And how does it exactly work.
I was trying to understand castalia code and found this:
simple ValueReporting like node.application.iApplication {
}
Like is used to define 'interfaces' that describe how a module looks like from the outside (i.e. you can define the number and name of gates in an interface). Modules can implement an interface using the like keyword (using the syntax in your question).
The advantage of this is, that when you use this interface in any other compound module, you don't have to specify the exact type of the module. Later you can drop into that place any module that implements the given interface (because from the outside, that module looks exactly the same as the interface itself).
Still, the best place to look for information is the OMNeT++ manual: https://omnetpp.org/doc/omnetpp/manual/#sec:ned-lang:submodule-like
The system I'm working on can be configurated with different boolean properties. The theorical maximum of different configurations is 2^n where n is the number of such properties.
There is a configuration tool separated from the production code, which uses boolean expressions to select which code packages are loaded.
This tool contains a class that defines methods like isWithX or more complex ones like isWithXwithoutYwithZ.
A package is basically a list of class extensions that define or redefine some method definitions.
Today the packages are named like myPackageWithAWithoutBwithCwithDwithoutE.
Since there is an evolving number of boolean configuration properties, the number of different packages and the size of their names is getting ridiculous and we can't see their names without scrolling all the time.
There is also a lot of code duplication.
EDIT: since production code has no access to the configurated properties the question is now limited to those issues:
list of package names for each package and each functionality
how many methods and how to name them
Right now the list of package names is basically all different combinations of names like this one: myPackageWithAWithoutBwithCwithDwithoutE except those where there is no behaviour specific to that configuration that we need to implement.
Right now for each package and each functionality: 1 method per package with the name of the functionality.
I cannot tell you how to solve your specific problem, so I will share with you some hints that might help you get started in finding the design that will actually work for you.
Consider a hierarchy of configuration objects:
ConfigurationSettings
ApplicationSettings
UserSettings
DisplaySettings
...
The abstract class ConfigurationSettings provides basic services to read/write settings that belong to any specific section. The hierarchy allows for simpler naming conventions because selectors can be reimplemented in different subclasses.
The ApplicationSettings subclass plays a different role: it registers all the sections in its registry instance variable, a Dictionary where the keys are section names and the values the corresponding subclass instances:
ApplicationSettings current register: anEmailSettings under: `Email`
The abstract class provides the basic services for reading and writing settings:
settingsFor: section
settingAt: key for: section
settingAt: key for: section put: value
Subclasses use these services to access individual settings and implement the logic required by the client to test whether the current configuration is, has, supports, etc., a particular feature or combination. These more specific methods are implemented in terms of the more basic settingAt:for:.
When a new package registers its own subclass its testing methods become available as follows:
self <section>Settings isThisButNotThat
where, for instance,
emailSettings
^(ApplicationSettings current for: 'Email') isThisButNotThat
and similarly for any other section. As I mentioned above, the division in subclasses will allow you to have simpler selectors that implicitly refer to the section (#isThisButNotThat instead of #isEmailThisButNotThat).
One other feature that is important to support Apply/Cancel dialogs for the user to modify settings is provided by two methods:
ConfigurationSettings >> #readFrom:
and
ConfigurationSettings >> #writeOn:
So, when you open the GUI that displays settings you don't open it on the current instance but on a copy of them
settings := ApplicationSettings new readFrom: ApplicationSettings current.
Then you present in the GUI this copy to the user. If the user cancels the dialog, you simply forget the copy. Otherwise you apply the changes this way:
settings writeOn: ApplicationSettings current
The implementation of these two services follows a simple pattern:
ApplicationSettings >> readFrom: anApplicationSettings
registry keysAndValuesDo: [:area :settings | | section |
section := anApplicationSettings for: area.
settings readFrom: section]
and
ApplicationSettings >> writeOn: anApplicationSettings
registry keysAndValuesDo: [:area :settings | | settings |
section := anApplicationSettings for: area.
settings writeOn: section]
I don't fully understand all of the aspects of your problem but maybe you could use a dynamic approach. For example, you could override #doesNotUnderstand: to parse the selector sent to the configuration and extract the package names:
doesNotUnderstand: aMessage
| stream included excluded |
"parse selectors like #isWithXwithoutYwithoutZ"
stream := (#isWithXwithoutYwithoutZ allButFirst: 6) asLowercase readStream.
included := Set new.
excluded := Set new.
[ stream atEnd ] whileFalse: [
(stream peek: 3) = 'out'
ifTrue: [
stream next: 3.
excluded add: (stream upToAll: 'with') ]
ifFalse: [ included add: (stream upToAll: 'with') ] ].
Then, all you need is a bit more code to generate the list of packages from that (I hope).
I am working on designing a puppet architecture for our company. I really like the idea of hiera and YAML files to classify my nodes. However, I would really like to be able to either apply YAML files that aren't based on facts or import YAML files into another YAML file.
For example NodeA.yaml
---
include webserver.yaml
include public.yaml
classes:
etc. . .
This would allow me to reuse my code as much as possible. That way when I make a change to my web server configs, I only have to do it in one file instead of every node's YAML file.
I'm open to other solutions as well.
YAML does not support import or include
(not recomended) You can use loadyaml from stdlib module to achieve desired functionality. Check this example of using loadyaml function.
You can easily achieve expected functionality just by designing a proper hiera hierarchy. I do not understand why you do not want to use facter facts? e.g: on each node define custom facter fact location. Next define a hiera hierarchy:
:hierarchy:
- "%{::location}"/"%{::fqdn}"
- "%{::location}"/common
- common
Next in file location_1/node1.yaml you define data specific only for that node1. In file location_1/common.yaml you define data common for all nodes in location_1. In common.yaml you define data common for all nodes.
If some data is common for all nodes you define it once in common.yaml and that's all. You do not have to redundantly define it in every node's yaml file.
How can I create a recipe that will populate its attributes using the fiels from an instance of an object in a generic way?
As an example, consider the following recipe:
component = $auth_docker
docker_image component.name do
registry component.registry
tag component.tag
action :pull
end
When you have 50s of recipes that look like this, maintaining them really gets overwhelming.
In Python, i would probably implement a solution that would look a bit like this:
docker_image = DockerImage(**$auth_docker)
Or, I would create some sort of helper function to build it for me:
def generate_docker_image_lwrp(attributes):
lwrp = DockerImage()
lwrp.registry = attributes.registry
lwrp.tag = attributes.tag
return lwrp
The goal is to reduce maintenance on the recipes. For instance this morning I wanted to add Chef's "retries" attribute on all recipes that pull an image. I had to edit all of them - I don't want that. I should've been able to a) add the attribute to the stack's JSON b) edit the Ruby wrapper class so that instances of it (i.e.: $auth_docker) get the "retries" field, then c) add the retries attribute to the lwrp-generator. Since all recipes would use the same generator, recipes wouldn't need to be edited at all.
Is this possible using Chef, in a way that 'notifies' still work?
Quoting the Documentation
A definition is code that is reused across recipes, similar to a
compile-time macro. A definition is created using arbitrary code
wrapped around built-in chef-client resources—file, execute, template,
and so on—by declaring those resources into the definition as if they
were declared in a recipe. A definition is then used in one (or more)
recipes as if it were a resource.
Though a definition behaves like a resource, some key differences
exist. A definition:
Is not a resource or a lightweight resource Is defined from within the
/definitions directory of a cookbook Is loaded before resources during
the chef-client run; this ensures the definition is available to all
of the resources that may need it May not notify resources in the
resource collection because a definition is loaded before the resource
collection itself is created; however, a resource in a definition may
notify a resource that exists within the same definition Automatically
supports why-run mode, unlike lightweight resources Use a defintion
when repeating patterns exist across resources and/or when a simple,
direct approach is desired. There is no limit to the number of
resources that may be included in a definition: use as many built-in
chef-client resources as necessary.
I.e: you can create a definition for this in a library cookbook used solely for this.
docker_library/defintions/default.rb
define :my_docker_image, :component => nil do
component = params[:component]
docker_image component.name do
registry component.registry
tag component.tag
action :pull
end
end
in your recipes (need to have a depends on the docker_library cookbook in the metadata.rb):
my_component = $auth_docker
my_docker_image my_component.name do
component my_component
end
A more complete exemple of definition is available in the logrotate cookbook