Puppet making one include depend on another within a class - puppet

I'm trying to get boxen set up and want to do something like this:
class mycompany::environment {
include iterm2::stable
include iterm2::colors::solarized_dark
}
And in my manifests/site.pp, I include mycompany::environment.
But iterm2::colors::solarized_dark is just configuration, and if it gets applied before iterm2 is actually installed, we get an error. How can I make that statement depend on the previous one (include iterm2::stable)?
I've looked at http://docs.puppetlabs.com/puppet/latest/reference/lang_relationships.html but I didn't understand all of it. Sorry, beginner to puppet here!

Class["iterm2::stable"] -> Class["iterm2::colors::solarized_dark"]
This is one way to do it.

Related

What is supposed to be in __init__.py

I am trying to create a Python package. You can have a look at my awful attempt here.
I have a module called imguralbum.py. It lives in a directory called ImgurAlbumDownloader which I understand is the name of the package -- in terms of what you type in an import statement, e.g.
import ImgurAlbumDownloader
My module contains two classes ImgurAlbumDownloader and ImgurAlbumException. I need to be able to use both of these classes in another module (script). However, I cannot for the life of me work out what I am supposed to put in my __init__.py file to make this so. I realize that this duplicates a lot of previously answered questions, but the advice seems very conflicting.
I still have to figure out why (I have some ideas), but this is now working:
from ImgurAlbumDownloader.imguralbum import ImgurAlbumDownloader, ImgurAlbumException
The trick was adding the package name to the module name.
It sure sounds to me like you don't actually want a package. It's OK to just use a single module, if your code just does one main thing and all its parts are closely related. Packages are useful when you have distinct parts of your code that might not all be needed at the same time, or when you have so much code that a single module would be very large and hard to find things in.

Why Is Doppl Trying To Pull in ReactiveStreams?

I am attempting to convert parts of an Android app to iOS using Doppl, and I am getting a strange result: Doppl keeps trying to pull in android.arch.lifecycle:reactivestreams, even though I don't want it to.
Specifically, in app/build/j2objcSrcGenMain/android/arch/lifecycle/, there is a reactivestrams/ subdirectory with R.h and R.m files in it. This seems to make Xcode cranky and may explain why I had some oddities with pod install.
My app/build.gradle has compile "android.arch.lifecycle:reactivestreams:$archVer", because my activity is using LiveDataReactiveStreams.fromPublisher(). However:
The activity is not in the translatePattern (and since its code is not showing up in app/build/j2objcSrcGenMain/, I have to assume that the translatePattern is fine)
I do not have a doppl statement related to reactivestreams, because there does not appear to be a Doppl conversion of this library (nor should it be needed here)
AFAIK, nowhere else in this app am I referring to LiveDataReactiveStreams, which AFAIK is the one-and-only public class from the reactivestreams library
So, the questions:
What determines whether Doppl creates R.h and R.m files for some dependency? It's not the existence of a doppl statement, as I have doppl statements for a lot of other dependencies (RxJava, RxAndroid, Retrofit) and those do not get R.h and R.m files. It's not whether the dependency is referenced from generated code, as my repository definitely uses RxJava and Retrofit, yet there are no R files for those.
How can I figure out why Doppl generates R.h and R.m for reactivestreams?
Once I get this cleared up... do I re-run pod install, or is there some other pod command to refresh an existing pod with a new implementation?
Look into 'app/build/generated/source/r/debug' and confirm there's an R.java being created for the architecture component. It'll be under 'android/arch/lifecycle/reactivestrams'.
I think there are 2 problems here.
Problem 1
Somehow Doppl/J2objc is of the opinion that this file should be transpiled. It could be either that 'translatePattern' matches with it, or that something in the shared code is referencing it. If you can't figure out which, please post a comment and I'll try to help (or post in slack group).
Problem 2
Regardless of why that 'R.java' is being sucked into the translate step, because of how stock J2objc is configured, the code is being generated with package folders instead of creating One Big Name. That generated file should be called 'AndroidArchLifecycleReactivestramsR.h' (and AndroidArchLifecycleReactivestramsR.m). Xcode really doesn't like package folders. That's why there's a slightly custom J2ojbc being used with Doppl, so we can have files with big names instead of folders.
In cases where you intentionally use package names that match with what J2objc considers to be "system" classes, you need to provide a header mapping file to force long names. The 'androidbase' doppl library needs to add a lot of files that are in the 'android' package, which J2objc considers "system". We override those names in the mapping file.
build.gradle
https://github.com/doppllib/core-doppl/blob/master/androidbase/build.gradle#L19
mapping file
https://github.com/doppllib/core-doppl/blob/master/androidbase/src/main/java/androidbase.mappings
I screwed up.
In my dopplConfig, I have:
translatePattern {
include '**/api/**'
include '**/arch/**'
include '**/RepositoryTest.java'
}
In this case, **/arch/** not only matches my arch package, but also the arch package from the Architecture Components.
Ordinarily, this would not matter, because the Architecture Components source code is not in my project. But, R.java gets generated, due to resources, and the translatePattern includes generated source code in addition to lovingly hand-crafted source code. So, that's where my extraneous Objective-C was coming from.
Many thanks to Kevin Galligan for his assistance with this, out on the #newbiehelp Doppl Slack channel!

Puppet 4: how to add calling class variables to scope of a defined type

In Puppet 3 and prior, templates in defines inherited scope from their calling class the same way native defined types do, so if I had a file resource with a template source created by a define, that template could make use of variables set in the calling class no matter which class called the define.
In Puppet 4 (also tested with Puppet 3.8 future parser), that appears to no longer be the case, and it is causing breakage that is hard to even measure in my environment, which has relied on this behavior for tens of thousands of lines of code. Is there any way at all to get this back? After looking into it, even converting the defines into native types doesn't solve the problem, as they rely on the ability to gather server-side information about what templates are available in different modules via custom functions, and everything in a native resource type appears to happen on the client.
Is this fixable, or do I attempt to wait for Puppet 5?
Edit: Don't get too caught up in the word 'scope' here -- I need any way to pass all class variables to a define and unpack them there so that they are available to templates, or a way to have a native type see what files are inside specified modules on the puppetmaster. I will accept any bizarre, obscure message passing option as long as it has this result, because the classes do not know where the templates are -- only the define does, because it's making use of the helper functions that scan the filesystem on the server.
Edit 2: To prove this works as expected in Puppet 3.8.5, use the following:
modules/so1/manifests/autotemplate.pp:
# Minimal define example for debugging
define so1::autotemplate (
$ensure = 'present',
$module = $caller_module_name,
) {
$realtemplate = "${module}${title}"
file { $title :
ensure => $ensure,
owner => 'root', group => 'root', mode => '0600',
content => template($realtemplate),
}
}
in modules/so2/manifests/example.pp:
# Example class calling so1::autotemplate
class so2::example (
$value = 'is the expected value'
) {
so1::autotemplate { '/tmp/qwerasdf': }
}
in modules/so2/templates/tmp/qwerasdf:
Expected value: <%= #value %>
In Puppet 3.8.5 with future parser off, this results in /tmp/qwerasdf being generated on the system with the contents:
Expected value: is the expected value
In Puppet 3.8.5. with parser = future in environment.conf (and also Puppet 4.x, though I tested for this example specifically on a 3.8.5 future parser environment), this results in the file being create with the contents:
Expected value:
Edit 3: two-word touch-up for precision
In Puppet 3 and prior, defines inherited scope from their calling class the same way native defined types do, so if I had a file resource with a template source created by a define, that template could make use of variables set in the calling class no matter which class called the define.
What you're describing is Puppet's old dynamic scoping. The change in scoping rules was one of the major changes in Puppet 3.0; it is not new in Puppet 4. There was, however, a bug in Puppet 3 that templates still used dynamic scope. That was fixed in Puppet 3.5, but only prospectively -- that is, when the future parser is enabled. Defined types themselves went through the scoping change in Puppet 3.0.0, along with everything else. The scope changes were a big deal (and Puppet devoted considerable effort to alerting users to them) when they first went into place, but nowadays there's no big deal here.
it is causing breakage that is hard to even measure in my environment, which has relied on this behavior for tens of thousands of lines of code.
I'm sorry you're having that experience.
Is there any way at all to get this back?
No. Puppet scoping rules do not work the way you want them to do. That they did work that way in templates (but not most other places) in Puppet 3 was and still is contrary to Puppet's documentation, and never intentional.
Is this fixable, or do I attempt to wait for Puppet 5?
There is no way to get dynamic variable scoping in templates or elsewhere in Puppet 4, and I have no reason to think that there will be one in Puppet 5.
If you need a template to expand host variables from the scope of a particular class, then you can get that by evaluating the template in the scope of that class. Alternatively, an ERB template can obtain variables from (specific) other scopes by means of the scope object. On the other hand, if you want to expand the template in the scope of a defined type, then you could consider passing the needed variables as parameters of that type.
There may be other ways to address your problem, but I'd need more details to make any other suggestions. (And that would constitute a separate question if you choose to ask it here on SO.)

Need to change source code of an installed library

I am using Python3.4. I have installed a certain "itunespy" library from GitHub with pip, to work with iTunes API.
(https://github.com/spaceisstrange/itunespy)
I can now access it from console by
import itunespy
Except the library is only searching the US store through iTunes Api, whereas I need to access the UK store. I looked into the code and found I only need to change two lines to fix my problem.
Please can you tell me how I can access and change the source code of an already installed library.
Thank you.
Fork the repository
Clone the forked repository
Make changes and push to your remote (origin, usually)
You may pip install from your fork
I took a look at source code, and:
a) you may obviously change your source code in locally-copied file
b) you may patch these constants in run-time, like adding this type of code to your main:
import itunespy
itunespy.base_search_url = "NEW_VALUE"
itunespy.base_lookup_url = "NEW_VALUE"
c) library API seems to provide country keyword argument, so you do not have to do any of these hacks mentioned above. Simply do:
itunespy.search_track('something', country='UK')
With this keyword argument, searches should work as expected without any modifications of source code.
you really want to change the sourcecode?
How about just change your implementation?
inherit from the class
override/overload their methods with your own
work with your inherited class and their methods
pro: if there are changes in the original library you will take them with you when you update (secure-patches etc.) but your overridden/overloaded methods are still the one you use.
otherwise if you really want to change the source code, take a branch from github and change the sourcecode as you need it like mentioned by dolftax

How do you tell Valgrind to completely suppress a particular .so file?

I'm trying to use Valgrind on a program that I'm working on, but Valgrind generates a bunch of errors for one of the libraries that I'm using. I'd like to be able to tell it to suppress all errors which involve that library. The closest rule that I can come up with for the suppression file is
{
rule name
Memcheck:Cond
...
obj:/path/to/library/thelibrary.so
}
This doesn't entirely do the job, however. I have to create one of these for every suppression type that comes up (Cond, Value4, Param, etc), and it seems to still miss some errors which have the library in the stack trace.
Is there a way to give Valgrind a single suppression rule to make it completely ignore a particular library? And even if there is no way to make such a rule which covers all suppression types, is there at least a way to create a rule which ignores all errors of a particular suppression type from a particular library?
For most of the suppression types, you omit the wildcard, like so:
{
name
Memcheck:Cond
obj:/path/to/lib/lib.so.10.1
}
{
name
Memcheck:Free
obj:/path/to/lib/lib.so.10.1
}
{
name
Memcheck:Value8
obj:/path/to/lib/lib.so.10.1
}
Note that you must list each type of error separately, you can't wildcard them. You must also list the entire pathname of the library (as shown by valgrind, with any "decorations" like version numbers).
Also, leaks are handled differently -- for those you need something that looks like this:
{
name
Memcheck:Leak
fun:*alloc
...
obj:/path/to/lib/lib.so.10.1
...
}
It appears that it is necessary to include a separate suppression record for each type of error (Cond, Value4, Param, etc). But based on my testing with valgrind-3.6.0.SVN-Debian, I believe you can use the following simplified form for each type of error...
{
<insert_a_suppression_name_here>
Memcheck:Cond
...
obj:/path/to/library/thelibrary.so.*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
...
obj:/path/to/library/thelibrary.so.*
...
}
The three dots are called frame-level wildcards in the Valgrind docs. These match zero or more frames in the call stack. In other words, you use these when it doesn't matter who called into the library, or what functions the library subsequently calls.
Sometimes errors include "obj:" frames and sometimes they only use "fun:" frames. This is based, in general, on whether or not that function is included in the library's symbol table. If the goal is to exclude the entire library, it may work best if the library does not include symbols so that you can exclude based on the library filename instead of having to create separate suppressions for each function call within the library. Hopefully, Valgrind is clever enough to suppress errors based on library filename even when it does know the function name, but I haven't verified this.
If you do need to add suppressions based on individual functions within the library, you should be able to use the same form...
{
<insert_a_suppression_name_here>
Memcheck:Leak
...
fun:the_name_of_the_function
...
}
Note: You can include --gen-suppressions=all on the valgrind command-line in order to see the exact form and names (including any C++ mangling) required to suppress each error. You can use that output as a template for your suppression records -- in which you would usually want to replace most lines with ... in order to simplify the process of suppressing all errors that might occur in association with a specific library or function call.
Note: <insert_a_suppression_name_here> is a placeholder in which you can type whatever descriptive text that you want. It is required to not be blank.
nobar's answer almost worked for me, but I was getting a syntax error:
==15566== FATAL: in suppressions file "suppresion.error.txt" near line 4:
==15566== bad or missing extra suppression info
==15566== exiting now.
For system calls, I needed to add an extra line as the docs state:
Param errors have a mandatory extra information line at this point,
which is the name of the offending system call parameter.
So I ended up with this and it worked:
{
<sup_mmap_length>
Memcheck:Param
mmap(length)
...
fun:function_from_offending_lib
...
}

Resources