I'm porting several Makefile projects in Gradle. I want every dependency to be versioned, so I created a common gradle file, namely general.gradle, that is included in each specific build.gradle file. For every project there is also a file dependencies.gradle, that contains a map {dependencyName, version}. Here an example:
ext.versions = [:]
versions.'libraryA'= "8a3f32"
versions.'libraryB'= "4af3e5"
I declare what libraryX refers to in general.gradle, inserting the libraries in the repositories, as follows:
repositories {
libs(PrebuiltLibraries) {
libraryA {
def libraryName = "${name}"
headers.srcDir "../${libraryName}"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${baseDir}/lib/${targetPlatform.name}/${buildType.name}/lib${libraryName}_" + versions."${libraryName}" + ".so")
}
}
libraryB {
def libraryName = "${name}"
headers.srcDir "../${libraryName}"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${baseDir}/lib/${targetPlatform.name}/${buildType.name}/lib${libraryName}_" + versions."${libraryName}" + ".so")
}
}
libraryC {....}
libraryD {....}
}
By this way, I can also set the right path depending on build type (debug or release) and platform (x86 or x86_64).
As you can see, inside every libraryX there is the very same code. I was wondering if I could avoid this unnecessary duplication, using a list
libraries = [ "libraryA", "libraryB", ...]
I tried doing:
repositories {
libs(PrebuiltLibraries) {
[ "libraryA", "libraryB", ...].each {
it {
def libraryName = "${name}"
headers.srcDir "../${libraryName}"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${baseDir}/lib/${targetPlatform.name}/${buildType.name}/lib${libraryName}_" + versions."${libraryName}" + ".so")
}
}
}
}
but I got this error:
Exception thrown while executing model rule: model.repositories > No signature of method: java.lang.String.call() is applicable for argument types: (general_dt1njom2wz075lo490p9e44em$_run_closure3_closure24_closure25_closure26_closure29) values:
[general_dt1njom2wz075lo490p9e44em$_run_closure3_closure24_closure25_closure26_closure29#2b2954e1]
Possible solutions: wait(), any(), wait(long), take(int), each(groovy.lang.Closure), any(groovy.lang.Closure)
Any idea?
Thanks,
Mauro
At this context it is a String variable:
[ "libraryA", "libraryB", ...].each {
it {
You cannot call it, it's not a method.
A method you want to call is delegated to closure, defined in third party context, but you can refer to it by using delegate:
[ "libraryA", "libraryB", ...].each {
delegate."$it" {
See also: http://docs.groovy-lang.org/latest/html/documentation/#_delegation_strategy
Related
Disabling the testsuite for my own cabal project is easy with cabal2nix, just supply --no-check. What about my project's dependencies? How can I disable compiling and running their testuites while building them?
Overriding each dependency (recursively!) with noCheck = false seems tedious. Is there some kind of overlay mechanism available?
There is indeed! To change something recursively for all packages, you can override the thing that generates all packages, and that's haskellPackages.mkDerivation. So this is doable with a Haskell package overlay like this:
hself: hsuper: {
mkDerivation = args: hsuper.mkDerivation (args // {
doCheck = false;
});
}
You can also override other arguments from here like this. For example you can disable library profiling builds, which commonly halves the build time:
hself: hsuper: {
mkDerivation = args: hsuper.mkDerivation (args // {
enableLibraryProfiling = false;
});
}
See this section in the manual for more info.
Edit: If you want to use this as a user overlay, you can put the following in ~/.config/nixpkgs/overlays/haskell-no-check.nix:
self: super: {
haskell = super.haskell // {
packageOverrides = hself: hsuper: {
mkDerivation = args: hsuper.mkDerivation (args // {
doCheck = false;
});
};
};
}
Note that this uses haskell.packageOverrides, not the somewhat deprecated packageOverrides in config.nix.
There are other ways of doing it, but I think in this case this is the best because it applies the change to all Haskell package sets. Unfortunately due to how overriding works, this would clear previous packageOverrides, which often isn't a problem, but can be. If you need to persist previous ones, then you can do this:
self: super: {
haskell = super.haskell // {
packageOverrides = super.lib.composeExtensions super.haskell.packageOverrides
(hself: hsuper: {
mkDerivation = args: hsuper.mkDerivation (args // {
doCheck = false;
});
});
};
}
I am new to puppet and I am trying to write a module to manage .bashrc file of 10 users. The following code is ok to manage the file of 1 user. However, I am unable to change the code to manage files for 10 users. I tried using defined types and variable with no luck. Can sombody please suggest me the right way to do this.
init.pp:
class profile (
$bashrc = $profile::params::bashrc,
$bashrc_host = $profile::params::bashrc_host,
) inherits profile::params {
anchor { 'profile::begin': } ->
class { '::profile::config': } ->
anchor { 'profile::end': }
}
config.pp:
class profile::config inherits profile {
file { $bashrc:
ensure => file,
source => "puppet:///$bashrc_host",
}
params.pp:
class profile::params {
$bashrc_host = "modules/profile/$fqdn_user1_bashrc"
}
case $::osfamily {
'RedHat': {
$bashrc = '/home/user1/.bashrc'
}
}
This is not at all a job for a class. As you noted yourself in your most recent comment, this calls for a define actually.
Please don't use verbs in the names of your defines. Instead of defineuser, just do
define profile::user($host_name) {
}
Off the top of my hat, I'm not aware of a good pattern to use module parameters in your defines. You can however use the following pattern:
class profile(
$default_shell = $profile::params::default_shell,
$default_prompt = $profile::params::default_prompt,
$users = {}
) inherits profile::params {
$defaults = { shell => $default_shell, prompt => $default_prompt }
create_resources('profile::user', $users, $defaults)
}
What happens is
values are taken from params, or hiera, or the invoking manifest
these values are gathered in the $defaults array
for any resource in the $users hash that has no shell or prompt, this default is used
If your aim of this module is to learn puppet then:
Add a param user to your class profile::params
class profile::params {
$bashrc_host = "modules/profile/$fqdn_user1_bashrc"
$user = 'user1',
}
case $::osfamily {
'RedHat': {
$bashrc = "/home/$user/.bashrc"
}
}
After this, you can use a combination of array or hiera and ensure_resource This still is not the most elegant solution, but baby steps.
If your intend is to actually manage the bashrc for various users, I would recommend using a pre existing module such as account
I would like to write a system groovy script which inspects the queued jobs in Jenkins, and extracts the build parameters (and build cause as a bonus) supplied as the job was scheduled. Ideas?
Specifically:
def q = Jenkins.instance.queue
q.items.each { println it.task.name }
retrieves the queued items. I can't for the life of me figure out where the build parameters live.
The closest I am getting is this:
def q = Jenkins.instance.queue
q.items.each {
println("${it.task.name}:")
it.task.properties.each { key, val ->
println(" ${key}=${val}")
}
}
This gets me this:
4.1.next-build-launcher:
com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty$ScannerJobPropertyDescriptor#b299407=com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty#5e04bfd7
com.chikli.hudson.plugin.naginator.NaginatorOptOutProperty$DescriptorImpl#40d04eaa=com.chikli.hudson.plugin.naginator.NaginatorOptOutProperty#16b308db
hudson.model.ParametersDefinitionProperty$DescriptorImpl#b744c43=hudson.mod el.ParametersDefinitionProperty#440a6d81
...
The params property of the queue element itself contains a string with the parameters in a property file format -- key=value with multiple parameters separated by newlines.
def q = Jenkins.instance.queue
q.items.each {
println("${it.task.name}:")
println("Parameters: ${it.params}")
}
yields:
dbacher params:
Parameters:
MyParameter=Hello world
BoolParameter=true
I'm no Groovy expert, but when exploring the Jenkins scripting interface, I've found the following functions to be very helpful:
def showProps(inst, prefix="Properties:") {
println prefix
for (prop in inst.properties) {
def pc = ""
if (prop.value != null) {
pc = prop.value.class
}
println(" $prop.key : $prop.value ($pc)")
}
}
def showMethods(inst, prefix="Methods:") {
println prefix
inst.metaClass.methods.name.unique().each {
println " $it"
}
}
The showProps function reveals that the queue element has another property named causes that you'll need to do some more decoding on:
causes : [hudson.model.Cause$UserIdCause#56af8f1c] (class java.util.Collections$UnmodifiableRandomAccessList)
This post refers to Puppet "require" not working as expected.
Is it possible to replace the Anchor Pattern with the function contain maintaining execution order and hinder declared classes of floating out. The two manifests look as follows:
class profile::maven inherits profile::base {
# Hiera
$version = hiera('profile::maven::version', '3.2.1')
$settings = hiera_hash('profile::maven::settings', undef)
$environments = hiera_hash('profile::maven::environments', undef)
include 'profile::java'
anchor { 'profile::maven::begin': }
class { '::maven::maven': version => $version, }
anchor { 'profile::maven::end': }
if ($settings) {
create_resources('::maven::settings', $settings)
}
if ($environments) {
create_resources('::maven::environment', $environments)
}
Anchor['profile::maven::begin'] -> Class['profile::java'] -> Class['::maven::maven'] -> Anchor['profile::maven::end']
}
and
class profile::java inherits profile::base {
# Hiera
$distribution = hiera('profile::java::distribution', 'jdk')
$version = hiera('profile::java::version', 'present')
anchor { 'profile::java::begin': }
class { '::java':
distribution => $distribution,
version => $version,
}
anchor { 'profile::java::end': }
# Parameters
$java_home = $::java::java_home
file { 'profile-script:java.sh':
ensure => present,
path => '/etc/profile.d/java.sh',
content => template('profile/java.sh.erb'),
}
Anchor['profile::java::begin'] -> Class['::java'] -> File['profile-script:java.sh'] -> Anchor['profile::java::end']
}
Because of the current issue PUP-1597 in Puppet 3.6.x, the profile classes have to be renamed, otherwise we get Error: undefined method 'ref' for nil:NilClass. Applying the changes result in:
class profile::mavenp inherits profile::base {
# Hiera
$version = hiera('profile::maven::version', '3.2.1')
$settings = hiera_hash('profile::maven::settings', undef)
$environments = hiera_hash('profile::maven::environments', undef)
include 'profile::javap'
class { '::maven::maven': version => $version, }
contain 'maven::maven'
if ($settings) {
create_resources('::maven::settings', $settings)
}
if ($environments) {
create_resources('::maven::environment', $environments)
}
Class['profile::javap'] -> Class['::maven::maven']
}
and
class profile::javap inherits profile::base {
# Hiera
$distribution = hiera('profile::java::distribution', 'jdk')
$version = hiera('profile::java::version', 'present')
class { '::java':
distribution => $distribution,
version => $version,
}
contain 'java'
# Parameters
$java_home = $::java::java_home
file { 'profile-script:java.sh':
ensure => present,
path => '/etc/profile.d/java.sh',
content => template('profile/java.sh.erb'),
}
}
Are these changes equivalent?
If someone has a better idea of how to the deal with technologcial dependencies in Puppet using the profile/role approach, do not hesitate to share your thoughts.
The latter pair of classes are not completely equivalent equivalent to the former. The biggest issue is in profile::javap. Note that its analog profile::java has this as part of its dependency chain:
Class['::java'] -> File['profile-script:java.sh']
Class profile::javap has no analog of that.
I'm not 100% certain whether class profile::mavenp is equivalent to class profile::maven, though I think it is. Your intent would be clearer and my uncertainty would be resolved if the former included
contain 'profile::javap'
instead of (or in addition to)
include 'profile::javap'
I have a module core and a class core::logrotate defined in core/manifests/logrotate.pp.
class core::logrotate {
#...some stuff here
#
define confd ($ensure = "present" , $log_name = "dummy" ) {
if ( $ensure == present )
{
file {
"/etc/logrotate.d/$log_name":
ensure => present,
source => filelookup("core/${log_name}.logrotate"),
}
} else {
file {
"/etc/logrotate.d/$log_name":
ensure => absent,
}
}
}
}
calling this function inside of templates.pp as
core::logrotate::confd { "mkill": log_name => mkill }
This fails with the error
Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: Invalid resource type core::logrotate::confd
If the puppet master version is 2.6.x then this fails, to make it work there used to be a import "*" in the init.pp of the module. Now removed this as moving to puppet 2.7.20.
The code pasted here works in 2.7 but fails in 2.6. Any idea why? how can I make it work for both 2.6 and 2.7?
You should take the define outside of the class, see the style guide: http://docs.puppetlabs.com/guides/style_guide.html#classes
Also, I think that you might be using modules wrong, it would be much more logical to have a 'logrotate' module on its own.
So; in modulepath/logrotate/manifests/confd.pp you'd put this:
define logrotate::confd ($ensure = "present" , $log_name = "dummy" ) {
if ( $ensure == present )
{
file {
"/etc/logrotate.d/$log_name":
ensure => present,
source => filelookup("core/${log_name}.logrotate"),
}
} else {
file {
"/etc/logrotate.d/$log_name":
ensure => absent,
}
}
}
That should make it work properly.
Greetings,
Ger