SaltStack: How to write pkgs by use regular expression in "sls"? - salt-stack

I use saltstack to deploy my servers.
I want to install all "tomcat7" pkgs on one server. So I write a sls file like this:
^tomcat7.*:
pkg:
- installed
- require:
- pkg: openjdk-7-jdk
But in the end, it receives an error:
----------
State: - pkg
Name: ^tomcat7.*
Function: installed
Result: False
Comment: Package ^tomcat7.* failed to install
Changes:
But in fact, the server has install all ^tomcat7.* packages sucessfully.
root#vagrant-ubuntu-raring-64:~# dpkg -l tomcat7*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-=====================================================-===============================-===============================-===============================================================================================================
ii tomcat7 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine
ii tomcat7-admin 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine -- admin web applications
ii tomcat7-common 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine -- common files
ii tomcat7-docs 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine -- documentation
ii tomcat7-examples 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine -- example web applications
ii tomcat7-user 7.0.35-1~exp2ubuntu1.1 all Servlet and JSP engine -- tools to create user instances
How to solve this problem? Am I need to write all ^tomcat7.* pkgs one by one?

So the problem here is that the pkg.installed state is checking the installed packages list for an exact match of ^tomcat7.*, without using regex. It finds that that package is not present, so it attempts to install it. The attempt works because the packaging system obviously does support regex. pkg.installed then checks the installed package list for ^tomcat7.* again (without regex), and finds it is still missing, so it reports an error.
The solution here could be to add another argument to pkg.installed which switches on regex matching. However, this makes the state less deterministic, because we will just search through the list of packages for a match on the regex, and will not verify that all the packages with that regex are installed. This could backfire if, for example, just the tomcat7 package had been installed previously. pkg.installed would see that there was a match, and not install the rest of the packages.
You'd be much better off to use the pkgs argument to give a list of all the exact packages you need. It is much more deterministic this way, and you know they will all be installed, even if one or more had been installed previously.

Related

How to use R styleR with pre-commit and renv

I have created a virtual environment with rvenv, so that I now have rvenv/ in my project root. I have also installed styler, and would like to have a pre-commit hook that will apply it to R code.
From here: https://github.com/lorenzwalthert/precommit/blob/master/.pre-commit-hooks.yaml is the following:
- id: style-files
name: style-files
description: style files with styler
args: [--style_pkg=styler, '--style_transformers=tidyverse_style(scope = "tokens")']
entry: inst/bin/style-files
language: script
files: '(\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$'
I'm confused about the path that should be given to entry:, in this snip it's a path to a global version of styler (or at least, I'm assuming so). But I would like to be able to use the version that I have installed in the virtual environment I assume.
My question is - how to go about doing this. If I shouldn't be using the version installed in renv/ then I'm happy to hear (and use) whatever the best practice is around creating a pre-commit hook to style R files that will work on mine and others systems.
Edit
Following the answer below worked, I had to install docopt as well (as outlined here).
Usually you rely on the remote repository to provide the configuration (such that you don't need all of the args / entry / etc. setup
for example if you want to use style-files from the repository you've listed you'd set this in your .pre-commit-config.yaml:
repos:
- repo: https://github.com/lorenzwalthert/precommit
rev: v0.1.2
hooks:
- id: style-files
from there you can customize args / etc.

How to scan a complete Symfony project for dependencies?

I am working on a Symfony 2.7 project. I ran composer update --dry-run to check which packages could need an update. Composer notified me about a deprecated package:
Package symfony/icu is abandoned, you should avoid using it. Use
symfony/intl instead.
I simply removed the dependency from the composer.json file and ran composer update --dry-run again. The message did not show up again, symfony/icu was uninstalled and symfony/intl was not installed.
Fine, this means that non of the other requirements depends on symfony/icu or symfony/intl. But can I be sure, that non of my own code requires any of these packages?
I created the project white a while ago and I do not remember why I added symfony/icu. I is possible, that the code that once required this packages has been removed, but I am not sure.
I used grep to search for any import of symfony/icu and found nothing. However that does not guarantee, that the package is not uses somewhere within my code, does it?
Is there any way to check if there are any dependencies within the complete Symfony project that require a specific package?
Check for every package? :(
I think you can do this only with automated testing.
There are no tools (I'm aware of) to detect whether some package is required to complete missing classes. There are also optional dependencies (package works without them, but with them will add some new features), so you will find missing classes but not required to run application.
How to check one package? :)
You heading right direction with grep. Yet rather look for namespace instead of package name. Package name is not always 1:1 to package namespace.
I would look for:
repo on Github: https://github.com/symfony/icu
open some file: https://github.com/symfony/icu/blob/1.2.x/IcuRegionBundle.php
find namespace
namespace Symfony\Component\Icu;
then search for "Symfony\Component\Icu" in code in PhpStorm or grep
I think the cleanest way is to start with composer and tell it dump all packages that caused your package to install:
For example, I'm trying to figure out why monolog/monolog is installed:
$ composer depends monolog/monolog
symfony/monolog-bundle 2.11.1 requires monolog/monolog (~1.18)
So monolog/monolog was installed because of symfony/monolog-bundle.
As you said you might have unintentionally use a package that's a dependency of another package so you didn't add it to your dependencies.
I'd use grep just as you did to search my source code. Just note that it's better to search for an actual class name, not the package name. Searching for package name would give you composer.json files but that's easier to analyze with composer depends than grep:
$ grep --include=\*.php -rnw './vendor' -e 'use Monolog'
./vendor/monolog/monolog/src/Monolog/ErrorHandler.php:16:use Monolog\Handler\AbstractHandler;
./vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php:14:use Monolog\Logger;
./vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php:45: throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter');
./vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php:14:use Monolog\Logger;
./vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php:13:use Monolog\Logger;
./vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php:34: throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
./vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php:14:use Monolog\Logger;
This command searches all *.php files and dups also line numbers containing Monolog.
Unfortunately, the these two methods just analyze your code post-mortem. Really the best way to avoid dealing with this is to write unit tests. Then clone your fresh repository, install dependencies with composer install and run tests. This should guarantee that your code is run in isolation from any other unwanted dependencies.

Can I install a .deb during a BitBake Build?

Problem Definition
I'm attempting to adapt these rosjava installation instructions so that I can include rosjava on a target image built by the BitBake build system. I'm using the jethro branch of Poky.
Implementation Attempt: Build From .deb with package_deb.bbclass
According to the installation instructions, all that really needs to be done to install rosjava is the following:
sudo apt-get install ros-indigo-rosjava
Which works perfectly fine on my build machine. I figured that if I can just point to a .deb and use the Poky metadata class package_deb, it would do all the heavy lifting for me, so I produced the following simple recipe adapted on this posting on the Yocto Project mailing list:
inherit package_deb
SRC_URI = "http://packages.ros.org/ros/ubuntu/pool/main/r/ros-indigo-rosjava/ros-indigo-rosjava_0.2.1-0trusty-20160207-031808-0800_amd64.deb"
SRC_URI[md5sum] = "2020ccc8b4a67dd918a9a2c426eece0b"
SRC_URI[sha256sum] = "ab9493fabe1285b0d21aab031348d0d733d116b0b2470bae90025709b303b649"
The relevant part of the errors I get during the above recipe's do_unpack are:
| no entry data.tar.gz in archive
|
| gzip: stdin: unexpected end of file
| tar: This does not look like a tar archive
| tar: Exiting with failure status due to previous errors
| DEBUG: Python function base_do_unpack finished
| DEBUG: Python function do_unpack finished
The following command produces the output below:
$ ar t python-rosdistro_0.4.5-1_all.deb
debian-binary
control.tar.gz
data.tar.xz
You can see here that there's a data.tar.xz, not data.tar.gz. What can I do to remedy this error and install from this particular .deb?
I've included package_deb in my PACKAGE_CLASSES variable and package-management in my IMAGE_FEATURES. I've tried other methods of installation which have all failed; I thought this method in particular would be very useful to know how to implement.
Update - 3/22
I'm attempting to circumvent the problems with the method above by doing my installation through a ROOTFS_POSTPROCESS_COMMAND which I've adapted from forum posts like this
install_rosjava() {
${STAGING_BINDIR_NATIVE}/dpkg \
--root=${IMAGE_ROOTFS}/ \
--admindir=${IMAGE_ROOTFS}/var/lib/dpkg/ \
-L /var/cache/apt/archives/ros-indigo-rosjava_0.2.1-0trusty-20160207-031808-0800_amd64.deb
}
ROOTFS_POSTPROCESS_COMMAND += " install_rosjava() ; "
However, this fails due to dpkg not being a command found within the ${STAGING_BINDIR_NATIVE} path. The Yocto Project Reference Manual states that:
STAGING_BINDIR_NATIVE Specifies the path to the /usr/bin subdirectory of the sysroot directory for the build host.
Taking a look inside this directory yields a lot of commands but not dpkg (The recipe depends on the dpkg package, and this command can be found in my target rootfs after the build is finished; I've also tried pointing to ${IMAGE_ROOTFS}/usr/bin/dpkg which yields the same results). From what I understand of the BitBake process, this command may be in another sysroot, but I must admit that this is where my understanding breaks down.
Can I adjust this method so that it works, or will I need to start from scratch on an installation from source?
Perhaps there's a different method entirely which I could consider?
If you really want to install their deb directly then your rootfs postprocess is one solution. It doesn't work because depending on dpkg will build you a dpkg for the target but you want a dpkg that will run on the host. Add a dependency on dpkg-native to your image.
Though personally I'd either inherit bin_package and extract the deb they provide then re-package it as a standard package in OE, or ideally write a proper recipe to build rosjava and submit it to meta-ros (https://github.com/bmwcarit/meta-ros).
package_deb is where the packaging machinery for deb packages is stored, it's not something you'd inherit in a recipe but should be listed in PACKAGE_CLASSES.
When you put a .deb in a SRC_URI the fetcher will try to unpack it so you can access the contents: the assumption is that you're going to repack the contents as a native Yocto recipe.
If that's what you want to do then first you'll need to fix the unpack logic (in bitbake/lib/bb/fetch2/__init__.py) to handle .debs with xz-compressed data. This is a bug in bitbake and a bug report and/or patch would be appreciated.
The alternative would be to use their deb directly but I don't recommend that as it's likely the dependencies don't match. The best long-term solution would be to build it from source directly instead of attempting to use a package for another distro.

Compiling haskell module Network on win32/cygwin

I am trying to compile Network.HTTP (http://hackage.haskell.org/package/network) on win32/cygwin. However, it does fail with following message:
Setup.hs: Missing dependency on a foreign library:
* Missing (or bad) header file: HsNet.h
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
If the header file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
Unfortuntely it does not give more clues. The HsNet.h includes sys/uio.h which, actually should not be included, and should be configurered correctly.
Don't use cygwin, instead follow Johan Tibells way
Installing MSYS
Install the latest Haskell Platform. Use the default settings.
Download version 1.0.11 of MSYS. You'll need the following files:
MSYS-1.0.11.exe
msysDTK-1.0.1.exe
msysCORE-1.0.11-bin.tar.gz
The files are all hosted on haskell.org as they're quite hard to find in the official MinGW/MSYS repo.
Run MSYS-1.0.11.exe followed by msysDTK-1.0.1.exe. The former asks you if you want to run a normalization step. You can skip that.
Unpack msysCORE-1.0.11-bin.tar.gz into C:\msys\1.0. Note that you can't do that using an MSYS shell, because you can't overwrite the files in use, so make a copy of C:\msys\1.0, unpack it there, and then rename the copy back to C:\msys\1.0.
Add C:\Program Files\Haskell Platform\VERSION\mingw\bin to your PATH. This is neccesary if you ever want to build packages that use a configure script, like network, as configure scripts need access to a C compiler.
These steps are what Tibell uses to compile the Network package for win and I have used this myself successfully several times on most of the haskell platform releases.
It is possible to build network on win32/cygwin. And the above steps, though useful (by Jonke) may not be necessary.
While doing the configuration step, specify
runghc Setup.hs configure --configure-option="--build=mingw32"
So that the library is configured for mingw32, else you will get link or "undefined references" if you try to link or use network library.
This combined with #Yogesh Sajanikar's answer made it work for me (on win64/cygwin):
Make sure the gcc on your path is NOT the Mingw/Cygwin one, but the
C:\ghc\ghc-6.12.1\mingw\bin\gcc.exe
(Run
export PATH="/cygdrive/.../ghc-7.8.2/mingw/bin:$PATH"
before running cabal install network in the Cygwin shell)

Loading Network.HTTP module in Haskell on GHC7.4.1

I am trying to load a file in GHCi (Windows 7 / Haskell Platform 2012.2.0.0 ) which starts with:
import Network.HTTP
import System.IO
...
But I get an error:
Could not find module `Network.HTTP'
This module is in HTTP package, right? So when I run >cabal list HTTP it finds the following:
* HTTP
Synopsis: A library for client-side HTTP
Default available version: 4000.2.3
Installed version: 4000.2.3
Homepage: https://github.com/haskell/HTTP
License: BSD3
Which means the package is installed right? What do I do wrong?
Thank you!
Having the package installed by cabal doesn't make it automatically available to your code. (For example, you could have installed 2 versions of some package, so it's not possible to determine automatically what to make available and what to hide).
Probably the simplest solution is to manage, build and run your project using cabal as well. See How to write a Haskell program, Section 2 describes (among other things) how to set up the files required by Cabal. In particular, your cabal file will contain a line similar to this:
build-depends: base, HTTP
See also Cabal User Guide.
Edit: You can try the following:
Create file test.cabal containing:
Name: test
Version: 0.0
Description: My network program
Build-Type: Simple
Cabal-Version: >=1.2
Executable test
Main-is: Test.hs
Build-Depends: base >= 4 && < 5, HTTP
(Replace Test.hs with your source file.) Then Run
cabal install --only-dependencies
this installs all required dependencies. If it all goes well, you can configure and build the project:
cabal configure
cabal build
Maybe to work interactively with your project, you could use cabal-ghci. I haven't tried it, but looks like it could be just what you need.

Resources