Nix(OS): Set "permittedInsecurePackages" only for one package build (in an overlay?) - overlay

I'd like to apply a configuration point only for a build I'm defining in an overlay in nix.
That is, I'd like to set
permittedInsecurePackages = [
"webkitgtk-2.4.11"
];
in an overlay. I want to do it there, because the overlay is to set up my claws-mail configuration; and I don't want to allow webkitgtk if I'm not installing claws-mail (which would potentially happen if I put it into ~/.config/nixpkgs/config.nix).
Is there a way to set this in an overlay? I tried setting it into self.config. or super.config., but neither worked.

You can't locally override configuration, but you can stop that configuration from getting in the way of the goal you're trying to accomplish.
The easy thing to do here is to clear meta.knownVulnerabilities in the copy of webkitgtk you pass to the claws-mail build.
To show how this can be done --
let
ignoringVulns = x: x // { meta = (x.meta // { knownVulnerabilities = []; }); };
webkitGtkIgnoringVulns = pkgs.webkitgtk24x-gtk2.overrideAttrs ignoringVulns;
in
pkgs.clawsMail.override { webkitgtk24x-gtk2 = webkitGtkIgnoringVulns; }
The above was tested in nix repl. In an overlay you might replace pkgs. with super. in referring to the original/unmodified versions of the packages at hand; it's still important to keep the webkitGtkIgnoringVulns in a let (or otherwise to not introduce it into the attrset your overlay evaluates to) if you don't want it to be defined in any other scope.
That is to say, to do this in an overlay might look like:
self: super: let
ignoringVulns = x: x // { meta = (x.meta // { knownVulnerabilities = []; }); };
in {
clawsMail = super.clawsMail.override {
webkitgtk24x-gtk2 = self.webkitgtk24x-gtk2.overrideAttrs ignoringVulns;
};
}

First, let me set a few things straight that will hopefully help you understand some NixOS and Nixpkgs concepts.
NixOS modules are mostly concerned with system configuration, whereas overlays are a mostly just a mechanism for making changes to the package set. These are separate features of two separate components (NixOS and Nixpkgs) that are distributed together.
What happens is that NixOS loads Nixpkgs when it evaluates. This can be controlled with some NixOS options. Most of these are simply passed to the Nixpkgs function (usually denoted import <nixpkgs>).
This means that NixOS configuration is in control of the config argument to Nixpkgs. However, overlays is merely another parameter of the Nixpkgs function that does not influence the Nixpkgs config.
Also note that self and super are just names that are typically given to the parameters of the function that defines an overlay. They are positional parameters, so you could give them different names if you need to. The result of an overlay function is an attribute set containing the attributes to add or update. self and super have no special meaning as attributes in Nixpkgs. (Although you did hide the super package)
So no, an overlay can not set a Nixpkgs config item. You may instead want to write a NixOS module instead. NixOS modules and NixOS configuration are the same thing.
Also note that NixOS (nixos-rebuild, etc) will not read ~/.config/nixpkgs/config.nix. It has it's own default.

Related

how to refresh application.conf at runtime

I update a key value in application.conf by setting the environment variable
play.http.secret.key=${?MY_SECRET_KEY}
But it still loads the previous value.
After a system reboot the change takes effect.
Is there a way to refresh the config file without rebooting?
Try the following:
Given in a file called sample1.conf:
a {
b {
c = 30
d = ["Red", "Orange", "Green", "Blue"]
}
}
If you wish to change a property be sure to change it as system property first and call invalidate caches then load again. This is also what allows you to override on the command line.
System.setProperty("a.b.c", "100")
ConfigFactory.invalidateCaches()
val config = ConfigFactory.load("sample1")
config.getDouble("a.b.c") should be (100.0)
Don't know if this would work in all scenarios. So it may or may not work with your application of choice.
AFAIK, there is no Out of the box mechanism to do such thing.
As it turns out, when you start Play through the "sbt run" command, it starts in Dev mode, creating two ClassLoaders, one for your code, and the other one for the immutable code, like libraries, dependencies, and the framework code itself. This is done this way as to provide the hot deploy feature, killing and reloading the first CL.
Because the application.conf is loaded by Play on start up, I would think that it is loaded within the fixed ClassLoader, hence no reload is possible.

Using a global object or parameters to pass config data, which one is better in Scala?

I'm newbie to Scala, and I have years of experience programming in Java.
Usually there are two patterns passing some config:
Using a global object sounds like "ConfigManager". And every time I
needs a config I get directly from it.
Passing the config through parameter. The config param may exists in
many layers in the program.
I choose one pattern depends on how the config will be used when I'm writing Java.
But in Scala, many people talks about eliminating side effects. This makes me wonder if I should use the second patterns at any costs.
Which pattern is better in Scala?
Global objects are bad: https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil
Make each component take it's configuration (individual pieces) as constructor parameters (possibly with some defaults). That prevents the creation of invalid components or components that have not been configured.
You can collect the initial processing of configuration values in a single class to centralize configuration code and to fail-fast when things are missing. But don't make your components (classes needing the configuration) depend on a global object or take in an entire configuration as a parameter. Just what they need as constructor params.
Example:
// centralize the parsing of configuration
case class AppConfig (config: Config) {
val timeInterval = config.getInt("type_interval")
val someOtherSetting = config.getString("some_other_setting")
}
...
// don't depend on global objects
class SomeComponent (timeInterval: Int) {
...
}
object SomeApplication extends App {
val config = AppConfig(ConfigFactory.load())
val component = new SomeComponent(config.timeInterval)
}
Use global object (this object stores only read-only immutable data, so no issues) which loads configuration object and config variables at once. This has many benefits over loading the configuration deep inside the code.
object ConfigParams {
val config = ConfigFactory.load()
val timeInterval = config.getInt("time_interval")
....
}
Benefits:
Prevents runtime errors (Fail fast approach).
If you have miss spelt any property name your app fails during startup as you are trying to fetch the data eagerly. If this were to be deep inside the codebase then it would be hard to know and it fails when the control of the program goes to that line. So, it cannot be easily detected unless rigorous testing is done.
Central place for all configuration logic and configuration transformations if any.
This serves as a central place for all config logic. easy to change and maintain.
Transformations can be done without need for refactoring the code.
Maintainable and readable.
Easy refactoring.
Functional programming point of view
Yes, loading the config file eagerly is great idea from Fail fast point of view but its not a good functional programming practice.
But important thing is you are not mixing the side effect with any other logic and keeping it separate during the loading of the app. So, as you are isolating the side effect and side effecting at the starting of your project, this would not be a program.
Once the side effecting is done and app has started. Your pure code base will not effected from this and remains pure and clean. So, though it is side effecting, it is isolated and does not effect your codebase. Benefits you again from this are worth experiencing, So go ahead.

Set a global variable for all mako templates using bottle?

I'm using bottle with beaker as session middleware. I'd like to include my session object in all my mako templates without specifying it when rendering:
Instead of this:
return mako_template("myView", {
"session" : bottle.request.environ.get('beaker.session')
})
just do this:
return mako_template("myView")
Is this possible? If so, how?
I don't know about Mako templates, but for Bottle SimpleTemplates you can use BaseTemplate.default:
bottle.BaseTemplate.defaults['session'] = bottle.request.environ.get('beaker.session')
However, since you are setting that at application instantiation time, bottle.request may not be valid. So you may need to turn it into something that does lazy evaluation when the value is requested.
Perhaps BaseTemplate.defaults gets fed into the Mako templates, or maybe Mako provides a similar mechanism for setting the defaults?
I hope this helps point you in the right direction.

Can I have dist-zilla fill in arbitrary fields in a template file?

Is there any way to have a user defined parameter in a file and then have the dist.ini set the value for the parameter. For example, a file might contain {{$THE_ANSWER}} and the dist.ini file would provide a value like THE_ANSWER = 42? I'm pretty new to using dist::zilla to work with perl distributions, and I'm having problems understanding how it treats files as templates. There seem to be only a couple of hard-codeed parameters, varying by plugin, that can be used for any file. One such parameter is the {{$NEXT}} variable made available by [NextRelease] in the Changes file.
I read through the tutorials and searched the modules on CPAN and can't figure out if this is even possible. It is not an acceptable work-around to use the [GenerateFile] plugin to put the whole file in the dist.ini file. Besides a lack of flexibility and just plain ugliness, it doesn't seem possible to add lines with leading white-space that way.
What I would do is use a stash or plugin to store the variables. Stashes are like plugins, but they don't do anything but store data, and they can be put into your global configuration as well as your dist.ini.
[%Vars]
favorite_pie = pumpkin
Then you can get at them like this:
$zilla->stash_named('%Vars')->favorite_pie
This assumes that you've made Dist::Zilla::Stash::Vars and given it a favorite_pie attribute.
You could make a totally generic stash, though, which accepts anything as a key. For that, I'd look at the source of Dist::Zilla::Plugin::Prereqs, which allows arbitrary configuration options and shoves them into a hash attribute in its BUILDSARGS method.
You could make that Dist::Zilla::Stash::Generic, and then register it as many times as you want for different reasons:
[%Generic / Pies]
favorite = pumpkin
hated = rhubarb
firstever = quince
[%Generic / Passwords]
pause = PeasAreDelicious
google = secret
reddit = SecretPeasAreDelicious
...then, as needed, say in templates...
{{ $zilla->stash_named('Passwords')->get_var('pause' }}
If I was making a lot of files that used this sort of generic thing, I'd pass their Text::Template instance a closure called get_password like this:
get_password => sub { $zilla->stash_named('Passwords')->get_var($_[0]) }
Then your template could include:
Login with: {{ get_password("pause") }}
This answer obviously leaves some source digging for you, but I think it should point at all the pieces I'd use to do what you want.

Sinatra coffeescript --bare?

I've done some searching on this, but I cannot find info. I'm building an application inside sinatra, and using the coffeescript templating engine. By default the compiled code is wrapped as such:
(function() {
// code
}).call(this);
I'd like to remove that using the --bare flag, so different files can access classes and so forth that I'm defining. I realize that having it more contained helps against variable conflicts and so forth, but I'm working on two main pieces here. One is the business logic, and arrangement of data in class structures. The other is the view functionality using raphaeljs. I would prefer to keep these two pieces in separate files. Since the two files wrapped as such cannot access the data, it obviously won't work. However, if you can think of a better solution than using the --bare option, I'm all ears.
Bare compilation is simply a bad practice. Each file should export to the global scope only the public objects that matter to the rest of your app.
# foo.coffee
class Foo
constructor: (#abc) ->
privateVar = 123
window.Foo = Foo # export
Foo is now globally available. Now if that pattern isn't practical, maybe you should rethink your structure a bit. If you have to export too may things, you nest and namespace things better, so that more data can be exposed through fewer global variables.
I support Alex's answer, but if you absolutely must do this, I believe my answer to the same question for Rails 3.1 is applicable here as well: Put the line
Tilt::CoffeeScriptTemplate.default_bare = true
somewhere in your application.