Specify default hosts for a task if no roles/hosts were provided - fabric

I would like to define default host(s) for a specific task in case no roles or hosts were explicitly provided from the command line.
I can use env.all_hosts to check the lists of current hosts is empty, but I don't know how to set it to some host.
I also considered using #hosts(), but it seems to override the input from the command line, which is undesirable.

You can override the #hosts decorator from the command line, using the command-line host lists, as described in the first point of Fabric's Order of Precedence:
Order of precedence
We’ve been pointing out which methods of setting host lists trump the others, as we’ve gone along. However, to make things clearer, here’s a quick breakdown:
Per-task, command-line host lists (fab mytask:host=host1) override absolutely everything else.
Per-task, decorator-specified host lists (#hosts('host1')) override the env variables.
Globally specified host lists set in the fabfile (env.hosts = ['host1']) can override such lists set on the command-line, but only if you’re not careful (or want them to.)
Globally specified host lists set on the command-line (--hosts=host1) will initialize the env variables, but that’s it.
Give that first option a try, and let us know if you have any other questions.

Related

How can I find out what my Apollo Graph Ref is?

You have specified an Apollo key but have not specified a graph ref; usage reporting is disabled. To enable usage reporting, set the APOLLO_GRAPH_REF environment variable to your-graph-id#your-graph-variant. To disable this warning, install ApolloServerPluginUsageReportingDisabled
I am struggling to find instructions for how to 'finish' the setup for an apollo classic graph. All of this worked fine last week but no longer does (I can see on Apollo's instructions page that something changed on 4 Oct and maybe requires people to change their graph reference).
I'm trying to solve these problems one step at a time, but cannot make sense of the instructions for apollo.
The format represented in the error message has two fragments, separated by an 'a' symbol. The format of the apollo key in the federation 2 instructions also has two fragments, but they are separated by a colon.
To find your-graph-id#your-graph-variant, log in to the apollo sutdio, got to settings and under the This Graph tab, look at the first section of General settings, you should find your-graph-id.
The variant is usually defaulted as current, i.e variant=current. If you have specified a different variant, be sure to use it.
In your .env you'd have to specify these two keys:
APOLLO_KEY=<your-apollo-api-key>
APOLLO_GRAPH_REF=<your-graph-id>#<current-or-your-variant>
Restart your server and you should be good.

How to check for an internal edge via TraCI?

I am trying to figure out whether an edge/lane is internal. When SuMO creates internal edges/lanes, it prefixes them with a colon [1]. Currently, I am exploiting this information, however, it seems that you also can annotate arbitrary other edges as internal using the tag function. This is also set for internal edges created by SuMO [1]. Therefore, I want to retrieve the information via TraCI.
To my knowledge, there is no TraCI command to retrieve this information (i.e. either the value of function or whether the edge/lane is internal).
The classes MSEdge and MSLane in the microsim directory have methods to retrieve both of those values, however, the classes Edge and Lane from libsumo do not.
I also checked whether the value of the function tag might get added to the parameter map during initialization, which I could access via TraCI's getParameter. This also does not seem to be the case. I checked some files from the netimport directory but could not find anything satisfactory.
Is there any other way to retrieve the function/isInternal information via TraCI without adding a new TraCI command (and the aforementioned missing methods in libsumo)?
This is a static property of the network so the easiest way of retrieving the information is to parse the network. In Python you can use sumolib for that:
import sumolib
net = sumolib.net.readNet("my.net.xml")
function = {}
for e in net.getEdges():
function[e.getID()] = e.getFunction()
There is currently no TraCI call for that but the colon thing is a very good indicator. The main developers are also a bit reluctant to add all static information retrieval to the TraCI API in order not to overload it.

Keeping preset (non-default) values when calling boost parseOptions

In my project I've got some internal config structures containing options registration using default values (let's say Config.x=0, Config.y=0), those values are not modifable for a client.
Sometimes users of my application want to modify default values of those fields before parsing command line arguments, so before parsing they just change those values manually (let's say Config.x=3, Config.y=4) and then fetch command-line/.ini ifle options and parse it using parseOptions.
If those external arguments contain only a part of those options i.e. Config.x=9, values of other options will be those which are registered using boost::program_options, not those currently assigned, so the result would be Config.x=9, Config.y=0 instead of Config.x=9, Config.y=4. So basically it seems that, boost::program_options::parseOptions clears all options before parsing.
Is there anyway to prevent boost from clearing already assigned options in case they do not appear in command-line arguments?
This can't be done. However, you should be able to create parsed_options either manually¹, or you can supply the options as a "faux" configfile so you can actually use the configfile parser on it.
Once you have the parsed_options you can store/notify them as usual.
¹ though this isn't supported/documented, see the comment at boost::program_option::basic_parsed_options<>

What is the difference between kubectl apply and kubectl replace

I am learning Kubernetes recently, and I am not very clear about the difference between "kubectl apply" and "kubectl replace". Is there any situation that we can only use one of them?
I have written up a thorough explanation of the differences between apply, replace, and patch: Kubernetes Apply vs. Replace vs. Patch. It includes an explanation that the current top-ranked answer to this question is wrong.
Briefly, kubectl apply uses the provided spec to create a resource if it does not exist and update, i.e., patch, it if it does. The spec provided to apply need only contain the required parts of a spec, when creating a resource the API will use defaults for the rest and when updating a resource it will use its current values.
The kubectl replace completely replaces the existing resource with the one defined by the provided spec. replace wants a complete spec as input, including read-only properties supplied by the API like .metadata.resourceVersion, .spec.nodeName for pods, .spec.clusterIP for services, and .secrets for service accounts. kubectl has some internal tricks to help you get that right, but typically the use case for replace is getting a resource spec, changing a property, and then using that changed, complete spec to replace the existing resource.
The kubectl replace command has a --force option which actually does not use the replace, i.e., PUT, API endpoint. It forcibly deletes (DELETE) and then recreates, (POST) the resource using the provided spec.
Updated Answer
My original was rather controversial and I would even say now, in hindsight, half incorrect. So here is an updated answer which I hope will be more helpful:
commands like kubectl patch, replace, delete, create, even edit are all imperative: they tell kubectl exactly what to do
the kubectl apply command is OTOH "declarative" in that it tells kubernetes, here is a desired state (the yaml from the file provided to the apply command), now figure out how to get there: create, patch, replace the object, etc whatever it takes... you get the idea.
So the 2 commands are hugely different.
EG with apply you can give it just the changes you want: it will figure out what properties of the object need to be changed, and leave the other ones alone; if those properties are "immutable" (eg, the nodeName of a pod), it will complain, and if you then repeat the command with --force, it is smart enough to know to do the equivalent of a replace --force.
In general, you should favor apply (with --force when necessary), and only use the imperative commands when the declarative approach does not give the expected result (although I would love to see examples of this -- I'm guessing this would happen only when you would need several steps because of interdependencies that will have negative consequences if done with apply).
The difference between apply and replace is similar to the difference between apply and create.
create / replace uses the imperative approach, while apply uses the declarative approach.
If you used create to create the resource, then use replace to update it. If you used apply to create the resource, then use apply to update it.
Note that both replace and apply require a complete spec, and both create the new resources first before deleting the old ones (unless --force is specified).
you can add option -v=8 when use kubectl, and you will find the log like this
apply --force
patch 422
delete 200
get 200
get 200
get 404
post 201
replace --force
get 200
delete 200
get 404
post 201
kubectl apply .. will use various heuristics to selectively update the values specified within the resource.
kubectl replace ... will replace / overwrite the entire object with the values specified. This should be preferred as you're avoiding the complexity of the selective heuristic update. However some resources like ingresses/load balancers can't really be replaced as they're immutable.
Example of the heuristic update leading to non obvious operation: https://github.com/kubernetes/kubernetes/issues/67135
From: https://github.com/kubernetes/website/blob/master/content/en/docs/concepts/cluster-administration/manage-deployment.md
Disruptive updates
In some cases, you may need to update resource fields that cannot be
updated once initialized, or you may just want to make a recursive
change immediately, such as to fix broken pods created by a
Deployment. To change such fields, use replace --force, which deletes
and re-creates the resource.

dynamic configuration with boost program_options

Is there a way to load a dynamic INI file like the one below.
[basic]
number_of_servers=3
[server1]
ip=10.20.30.40
password=sdfslkhf
[server2]
ip=10.20.30.41
password=sdfslkhf
[server3]
ip=10.20.30.42
password=sdfslkhf
Here the idea is that the servers that are defined here is very specific to the software's deployment; so the admin decides how many servers participate in the configuration.
Is there a way to handle this in boost program_options?
Another, potentially more standard way, would be like this:
[basic]
number_of_servers=3
[server]
name=server1
ip=10.20.30.40
password=sdfslkhf
[server]
name=server2
ip=10.20.30.41
password=sdfslkhf
[server]
name=server3
ip=10.20.30.42
password=sdfslkhf
This way you don't need to worry about undefined section names, and I think this style is more widely used as well (definitely it's how QuickFIX does it, in a way very similar to what I outlined).
And you can probably remove the number_of_servers entry, and just use the count() function to find how many server sections there are.
There is an optional bool parameter to allow for unregistered entries in the parse_config_file function. It's set to false by default. See the documentation here:
http://www.boost.org/doc/libs/1_45_0/doc/html/boost/program_options/parse_config_file_id991860.html
If you call this function with true then it will add any unregistered entries into the variables_map as strings. You can check whether they exist with the variables_map::count function.
I hope that helps.
Sure you can. The server sections have a pattern: just load all those matching the pattern into a list of servers.
The challenges I faced while resolving this was to make sure the sections are kept together and are no way mixed up.
In the end I relied on a options_description with the known/finite options and then using the parsed_options that come out of parse_config_file, I had to collect all unrecognized options ( collect_unrecognized ). Then I had to iterate it to pick the options in order.
Thanks every one for their contribution.