Attribute Resolution in Chef - attributes

I'm using a chef community cookbook that downloads, installs, a configures an SDK. (Let's call it the blah-sdk.) You just include_recipe 'blah-sdk' and viola, it's installed. It has an attribute specifying the version of the blah-sdk it will install. This version attribute in turn is used to form the value of a corresponding 'download_url' attribute. In theory I should be able to set the value of version attribute to something else in the cookbook where I include the blah-sdk. But there is a problem. The download_url attribute gets set (using the default version specified in the blah-sdk cookbook) before my override version attribute does. So the wrong url is used to retrieve the default version rather than the version I want. I could set the download_url in my cookbook as well, but that breaks the encapsulation of the 'blah-sdk' cookbook. I also might end up playing whack-a-mole experimentally with some long stream of attributes before getting it to work. There has got to be a better way. What is it?
cookbooks/blah-sdk/attributes/default.rb:
default['blah']['version'] = '24.4'
default['blah']['download_url'] = "http://dl.company.com/blah/blah-sdk_r#{node['blah']['version']}-linux.tgz"
cookbooks/blah-sdk/recipes/default.rb:
...
print("blah version: #{node['blah']['version']}")
print("blah download_url: #{node['blah']['download_url']}")
...
cookbooks/my_cookbook/attributes/default.rb:
normal['blah']['version'] = '24.4.1'
(I've also tried using default, force_default, override, and force_override. Made no difference.)
cookbooks/my_cookbook/recipes/default.rb
...
include_recipe 'blah-sdk'
...
Output:
==> default: blah version: 24.4.1
==> default: blah download_url: http://dl.company.com/blah/blah-sdk_r24.4-linux.tgz
Code demonstrating the issue and coderanger's suggested solution (if you can fix the third party cookbook):
https://github.com/marc-swingler/stackoverflow_question
Not the best solution, but due to the order in which attributes are loaded, dropping the version into a role or environment works too.
https://christinemdraper.wordpress.com/2014/10/06/avoiding-the-possible-pitfalls-of-derived-attributes/

See https://coderanger.net/derived-attributes/ for an overview of this problem. There is no good solution that doesn't involve modifying the upstream cookbook. Easiest solution is to duplicate the derived attribute in your wrapper as well.

Related

Why is rspec-puppet behaviour different for hiera lookup using 'lookup' or 'hiera' functions?

Running rake spec tests I am getting:
Warning: The function 'hiera' is deprecated in favor of using 'lookup'. See
https://docs.puppet.com/puppet/4.10/reference/deprecated_language.html
(file & line not available)
So I decided to change to using lookup. However my hiera lookups are now not working
v1 = lookup('key') # doesn't work
v2 = hiera('key', undef) #works
I'm using rspec-puppet-2.5.0 and onceover 3.2.0, because otherwise other things don't work with the Puppet Enterprise version we're using (equivalent to puppet 4.7.0) (don't you just love Ruby versioning).
What I suspect is that something in the interception of lookup by rspec-puppet is not working properly and the correct hiera.yaml is not being found. Before I go debugging I was wondering if someone had already seen this?
Thanks a lot #matt-schuchard. That is the very reason: the hiera config v3. So I was approaching the refactor in the wrong direction. First upgrade the hiera and then the puppet code itself is the correct sequence for this.

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

JAXB-XJC Xpropertyaccessors

Per JAXB specification http://jaxb.java.net/2.2.4/docs/xjc.html if you want to run the JAXB-XJC compiler, one of the of the extensions/arguments you may pass is -Xpropertyaccessors even though it has been specfied in each of JAXB-RI till the latest one 2.2.5u2 still when I try to run it passing this argument I get 'unrecognized parameter -Xpropertyaccessors' is not specified in the help menu when I run it. It is important for me to have the access levels on properties not fields.
I have followed up with the JAXB RI lead, apparently the plugin is there but not enabled. The issue will be fixed in versions 2.1.14 and 2.2.6 of the JAXB RI. I would recommend entering a bug so that you will be able to track the status of the issue.
http://java.net/jira/browse/JAXB/

documentation for cabal-install configuration file

The ~/.cabal/config stores configuration which cabal-install uses. I wanted to do some hackery on it. (Specifically, having multiple GHC versions installed, I wish to have separate documentation indexes).
I couldn't, however, find any documentation about its' syntax or variables except for what is included in default file. Is there any documentation available?
Edit: I've stated the goal above, but let me add some details: If the same package (eg. GTK) is installed in two versions of GHC they end up in the same documentation index file. I wan't that local documentation index to be separate for each GHC installation. I believe it is possible in some way using documentation directory setting, but there has to be a variable for currently used GHC version. If there isn't one there might be some workarounds available, but I won't be able to say that unless I see the documentation.
This seems to work, although I've only tested it with one version of GHC:
documentation: True
doc-index-file: $datadir/doc/$compiler/index.html
install-dirs user
docdir: $datadir/doc/$compiler/$pkgid
With the other options left at the default, this generates documentation in .cabal/share/doc/<ghc-version>/<package-name>, and the index in .cabal/share/doc/<ghc-version>/index.html.
There appears to be very little online - not even the haddocks for the cabal-install code. So your best bet may be to puzzle it out from the source. cabal unpack cabal-install, or view the cabal-install repo online. Look at SavedConfig in Distribution/Client/Config.hs. As an example, it imports GlobalFlags from Setup.hs; the individual flags, eg globalCacheDir, are associated with their config-file syntax (which is also the command-line syntax) in the globalCommand function below, remote-repo-cache in this case.
You should also ask dcoutts in the #haskell channel on irc.freenode.net, in case he has new docs available.

Node INTL locale Collation

I'm working on a side project that involves sorting Japanese and Thai strings. When I was testing the sorting in client-side Javascript, I was able to use a.localeCompare(b, "languageCode") which worked. When I tried this same logic in Node, it did not work, because the Node INTL object is restricted to English as the default.
I want to customize my node build as described in the above link, and came across the ICU4C-data Node Module, which I understand contains a full set of ICU data. I've been playing around with different build flags, like the one specified by the (sparse) README: --icu-data-dir=node_modules/icu4c-data, to no avail - no matter which flags I set I cannot get the INTL Collator's compare function to give the expected results. Is there an obvious flag that I'm missing, or key assumption I have wrong?
Here are a few things important notes/resources:
The end goal is Thai & Japanese collation - if there's another approach using Node to implement this, I'm open to suggestions.
Collation must be done in Node
I'm going to be relying on Array.prototype.sort() - mainly looking for a comparator
Using Node 0.12, with ECMA support
My first time customizing a Node build (~1 month experience)
Install the full-icu package instead. It will give instructions on how to load the rest of the data.
Also note that future node versions should not require any configuration to pick up the new data, you can see #3460 if interested.
I need to fix the icu4c-data's readme to reflect this.

Resources