How to remove newly created directory not part of rpm package - shell

I am new to rpm creation. I need to find a way to install/uninstall/upgrade a plugin in jenkins using rpm.I am able to install plugin using rpm , but on un-installation how can I delete new file/directory which was not part of the package.
Suppose my package only deploys xyz.jpi file on server which on server restart creates xyz.jpi and xyz folder . On uninstallation I want to remove both created folders .

you can use the %ghost directive in the %files section; which means "this file/folder does not exist yet, but when it appears it will be mine."
%files
%ghost %dir /path/to/unexisting/xyz
If there will be files present in that directory; I am not sure rpm will remove them. In that case it might be necessary to add another line (to be tested!)
%ghost /path/to/unexisting/xyz/*
more information in the documentation

How about in %postun section check if this is the last instance of the package who owns this folder.
E.g:
In our case all products (a,b,c) co-own /opt/xyz then the last of a, b, c on its uninstall remove the /opt/xyz folder (if it is not installed by rpm).
we are checking this by rpm -qa | egrep 'b|c' ....
if nothing present then we do rm -rf /opt/xyz

Related

Creating a go binary as debian binary package for a custom repository

I am trying to package a binary written in Go as a debian/ubuntu binary package. This would be available for download from a custom web server and apt key.
I am - very - confused.
I looked at https://wiki.debian.org/Packaging/Intro?action=show&redirect=IntroDebianPackaging first. This looks like exhaustive, without wanting to say too complex.
What confuses me is that the file debian/rules contains a make command. But we don't have a Makefile, do I need to create one?
In fact I am at the debuild -us -uc step, and it obviously failed.
Then I saw this: https://askubuntu.com/a/251892 , where it says:
Avoid the Debian bureaucracy by just building the binary:
dpkg-buildpackage -b
I did that, and the command completed, but looking at the generated package there it doesn't contain any binaries, only a changelog.gz and a copyright file in the app folder below /usr/share/doc.
So I am lost, I have no idea which tutorial to follow here to build a binary custom package, which, btw, later will be available for download signed. Obviously it is my first debian/ubuntu package I am creating.
I'm currently working on a project written in go that is distributed as a .deb package in a repository.
I have to tell you that it is not easy to find documentation about it. I use fpm for that activity.
First create in a folder that represents your project on the destination computer. For example "/tmp/proj"
Inside that folder you must put everything you want to distribute in the package. For example, if your compiled binary is called "myapp" and you want to put it in "/usr/bin/", then you have to create the folder "/tmp/proj/usr/bin" and put in it the executable file with the permissions you will use.
This way with all the files you want to distribute.
Then create a script that you will use to generate the package:
PKG_NAME= application name, one word, lowercase
PKG_DESCRIPTION= Brief description of the package
PKG_VERSION= Version, in x.y.z format
PKG_RELEASE= Correlative number from 1 onwards
PKG_MAINTAINER= Your name and email. Format: "name" < email >
PKG_VENDOR= Your company name
PKG_URL= URL of your product
FPM_OPTS="-n $PKG_NAME -v $PKG_VERSION --iteration $PKG_RELEASE"
fpm -s dir -t deb ${FPM_OPTS} -f \
-maintainer "$PKG_MAINTAINER" \
--vendor "$PKG_VENDOR" \
--url "$PKG_URL" \
--description "$PKG_DESCRIPTION" \
--architecture "amd64" \
-C /tmp/proj \
.
And that's it!
Well, there's a lot to learn.

How to package a Kivy app with Pyinstaller

I have a lot of troubles following the instructions form the Kivy website, many steps aren't explained like what should I answer to the warning.
WARNING: The output directory "..." and ALL ITS CONTENTS will be REMOVED! Continue? (y/n)
Even if I choose y, the folder isn't removed.
Also should I always add these lines:
from kivy.deps import sdl2, glew
Tree('C:\\Users\\<username>\\Desktop\\MyApp\\'),
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)]
in the .spec file? Why are they necessary?
Not many info is available for Kivy.
Because I spent a lot of time understanding how I should package my app, here are some instructions that would have really helped me.
Some info are available at http://pythonhosted.org/PyInstaller/
Python 3.6 as of march 2017
Because packaging my app gave me the error IndexError: tuple index out of range, I had to install the developement version of PyInstaller:
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
Step 1:
I moved all the files of MyApp in a folder "C:\Users\<username>\Desktop\MyApp": the .py, the .kv and the images and I created an icon.ico.
I created another folder C:\Users\<username>\Desktop\MyPackagedApp. In this folder I press Shift+right click and select open command window here.
Then I pasted this:
python -m PyInstaller --name MyApp --icon "C:\Users\<username>\Desktop\MyApp\icon.ico" "C:\Users\<username>\Desktop\MyApp\myapp.py"
This creates two folders, build and dist, and a .spec file. In dist/MyApp, I can find a .exe. Apparently, if my app is really simple (just one label), the packaged app can works without the Step 2.
Step 2:
The second step involves editing the .spec file. Here is an exemple of mine.
(cf Step 3, for the explanations about my_hidden_modules)
I go back to the cmd, and enter
python -m MyApp myapp.spec
I then got this warning:
WARNING: The output directory "..." and ALL ITS CONTENTS will be REMOVED! Continue? (y/n)
I enter y and then press enter.
Because I choosed y, I was surpised that the folder build was still there and that the dist/MyApp was still containing many files. But this is normal. PyInstaller can output a single file .exe or a single folder which contains all the script’s dependencies and an executable file. But the default output is a single folder with multiple files.
Step 3: adding hidden modules
When I click on the myapp.exe in dist/MyApp, the app crashed. In the log C:\Users\.kivy\logs\ I could find 2 errors: ModuleNotFoundError: No module named 'win32timezone' and SystemError: <class '_frozen_importlib._ModuleLockManager'>.
Because of this I had to edit the .spec file and add these lines:
my_hidden_modules = [
( 'C:\\Users\\<username>\\AppData\\Local\\Programs\\Python\\Python36\\Lib\\site-packages\\win32\\lib\\win32timezone.py', '.' )
]
in a = Analysis I changed datas = [] to datas = my_hidden_modules,
Apparently this is because I used a FileChooser widget.
So, the line:
ALL ITS CONTENTS will be REMOVED!
yes, it will be removed AND replaced later with new files. Check the date. I think it prints permission denied if it can't do such a thin both for files and the whole folder, so you'd notice it. It's important though, because you need to add additional files into your folder.
Those additional files of two types:
kivy dependencies
application data
Dependencies are just binaries (+/- loaders, licenses, or so), you get them through the *[Tree(p) ...] piece of code, which is just a command for "get all files from that folder". Without them Kivy won't even start.
Similarly to that, the second Tree(<app folder>) does the same, but for your own files such as .py files, .kv files, images, music, databases, basically whatever you create.
Obviously if you remove the deps, app won't start and if you remove app data, you'll get some path errors and most likely crash. You don't want any of that :P
It also works if in the 'a = Analysis...' block in the spec file one substitutes
hiddenimports=[]
for
hiddenimports=['win32file', 'win32timezone']
for win32file, win32timezone or for whatever files are missing

Why am I getting this error in my Primer3/eprimer3 Mac OSX build?

I'm getting this error on my mac osx build.
Primer3/eprimer3 issue:
Error: thermodynamic approach chosen, but path to thermodynamic parameters not specified
From:
http://www.mcardle.wisc.edu/mprime/help/primer3/primer3_manual.htm#globalTags
PRIMER_THERMODYNAMIC_PARAMETERS_PATH (string; default ./primer3_config)
This tag specifies the path to the directory that contains all the parameter files used by the thermodynamic approach. In Linux, there are two default locations that are tested if this tag is not defined: ./primer3_config/ and /opt/primer3_config/. For Windows, there is only one default location: .\primer3_config\.
I put the primer3_config in my PATH in bin and still cannot solve this issue. I even did:
export PRIMER_THERMODYNAMIC_PARAMETERS_PATH=/Users/jared/Downloads/primer3-2.3.2/src
and
export PRIMER_THERMODYNAMIC_PARAMETERS_PATH=/Users/jared/Downloads/primer3-2.3.2/src/primer3_config
to no avail.
According to the primer3 manual:
1.5. IMPORTANT: because PRIMER_THERMODYNAMIC_ALIGNMENT=1
PRIMER_THERMODYNAMIC_PARAMETERS_PATH must point to the right location.
This tag specifies the path to the directory that contains all the
parameter files used by the thermodynamic approach. In Linux, there
are two default locations that are tested if this tag is not
defined: ./primer3_config/ and /opt/primer3_config/. For Windows,
there is only one default location: .\primer3_config. If the the
parameter files are not in one these locations, be sure to set
PRIMER_THERMODYNAMIC_PARAMETERS_PATH.
So if you download and compile primer3 form source using the Make command, to get primer3 to run globally you need to copy the executueable, primer3_core, to your path and place the configuration directory, primer3_config in that same directory or at /opt/primer3_config
cd src
sudo cp primer3_core /usr/local/bin # or /usr/bin
sudo cp -r primer3_config /opt/
I has the same issue. I had installed Primer 3 using homebrew-science which was pretty painless. https://github.com/Homebrew/homebrew-science
I did try copying the primer3_config directory into the homebrew primer3 directory, ie:
/usr/local/Cellar/primer3/2.3.4/bin/primer3_config but this also did not work.
In the end I added the PRIMER_THERMODYNAMIC_PARAMETERS_PATH configuration to the primer 3 input file, and this worked. Note that the directory name must have a trailing slash. It is the last entry in the file below which is copied from the example file in the primer3 sources.
SEQUENCE_ID=example
SEQUENCE_TEMPLATE=GTAGTCAGTAGACNATGACNACTGACGATGCAGACNACACACACACACACAGCACACAGGTATTAGTGGGCCATTCGATCCCGACCCAAATCGATAGCTACGATGACG
SEQUENCE_TARGET=37,21
PRIMER_TASK=pick_detection_primers
PRIMER_PICK_LEFT_PRIMER=1
PRIMER_PICK_INTERNAL_OLIGO=1
PRIMER_PICK_RIGHT_PRIMER=1
PRIMER_OPT_SIZE=18
PRIMER_MIN_SIZE=15
PRIMER_MAX_SIZE=21
PRIMER_MAX_NS_ACCEPTED=1
PRIMER_PRODUCT_SIZE_RANGE=75-100
P3_FILE_FLAG=1
SEQUENCE_INTERNAL_EXCLUDED_REGION=37,21
PRIMER_EXPLAIN_FLAG=1
PRIMER_THERMODYNAMIC_PARAMETERS_PATH=/usr/local/Cellar/primer3/2.3.4/bin/primer3_config/
=
Then run it like this:
$ primer3_core < example2

How can I configure Module::Build to NOT install files as read-only?

I've encountered a scenario where I'm building a Perl module as part of another Build system on a Windows machine. I use the --install_base option of Module::Build to specify a temporary directory to put module files until the overall build system can use them. Unfortunately, that other Build system has a problem if any of its files that it depends on are read only - it tries to delete any generated files before rebuilding them, and it can't clean any read-only files (it tries to delete it, and it's read only, which gives an error.) By default, Module::Build installs its libraries with the read-only bit enabled.
One option would be to make a new step in the build process that removes the read-only bit from the installed files, but due to the nature of the build tool that will require a second temporary directory...ugh.
Is it possible to configure a Module::Build based installer to NOT enable that read-only bit when the files are installed to the --install_base directory? If so, how?
No, it's not a configurable option. It's done in the copy_if_modified method in Module::Build::Base:
# mode is read-only + (executable if source is executable)
my $mode = oct(444) | ( $self->is_executable($file) ? oct(111) : 0 );
chmod( $mode, $to_path );
If you controlled the Build.PL, you could subclass Module::Build and override copy_if_modified to call the base class and then chmod the file writable. But I get the impression you're just trying to install someone else's module.
Probably the easiest thing to do would be to install a copy of Module::Build in a private directory, then edit it to use oct(666) (or whatever mode you want). Then invoke perl -I /path/to/customized/Module/Build Build.PL. Or, (as you said) just use the standard Module::Build and add a separate step to mark everything writable afterwards.
Update: ysth is right; it's ExtUtils::Install that actually does the final copy. copy_if_modified is for populating blib. But ExtUtils::Install also hardcodes the mode to read-only. You could use a customized version of ExtUtils::Install, but it's probably easier to just have a separate step.

Mogenerator and Xcode 4

I just installed mogenerator+xmo'd on my development machine and would like to start playing with it. The only instructions I could really find online were from a previous SO post, and those don't work with XCode 4 (or at least ⌘I doesn't pull up metadata any more and I don't know how).
So to get things up and running, is all that needs to happen to add xmod in the .xcdatamodeld's comments (wherever they are) and the classes will be generated/updated on save from then on?
While trying to find this answer myself, I found MOGenerator and Xcode 4 integration guide on esenciadev.com. This solution is not a push-button integration, but it works. The link has detailed instructions, but generally you:
Copy the shell scripts into your project
Add build rules to your target to run the two shell scripts
When you build your project, the script runs MOGenerator on all .xcdatamodel files in your project directory. After the build, if the script generates new class files, you must manually add them to your project. Subsequent builds will remember existing MO-Generated files.
Caveats:
The example's build rule assumes you put the scripts into a /scripts/ file folder within your project directory. When I ignored this detail (creating a project folder but not a file folder) I got a build error. Make sure the build rule points to the script's file location.
The script uses the --base-class argument. Unless your model classes are subclasses of a custom class (not NSManagedObject), you must delete this argument from the script. E.g.,
mogenerator --model "${INPUT_FILE_PATH}/$curVer" --output-dir "${INPUT_FILE_DIR}/" --base-class $baseClass
Now that Xcode 4 is released Take a look at the Issues page for mogenerator
After I make changes to my model file, I just run mogenerator manually from the terminal. Using Xcode 4 and ARC, this does the trick:
cd <directory of model file>
mogenerator --model <your model>.xcdatamodeld/<current version>.xcdatamodel --template-var arc=YES
Maybe I'll use build scripts at some point, but the terminal approach is too simple to screw up.
I've found a Script in the "Build Phases" to be more reliable than the "Build Rules".
Under "Build Phases" for your Target, choose the button at the bottom to "Add Run Script". Drag the run script to the top so that it executes before compiling sources.
Remember that the actual data model files (.xcdatamodel) are contained within a package (.xcdatamodeld), and that you only need to compile the latest data model for your project.
Add the following to the script (replacing text in angle-brackets as appropriate)
MODELS_DIR="${PROJECT_DIR}/<path to your models without trailing slash>"
DATA_MODEL_PACKAGE="$MODELS_DIR/<your model name>.xcdatamodeld"
CURRENT_VERSION=`/usr/libexec/PlistBuddy "$DATA_MODEL_PACKAGE/.xccurrentversion" -c 'print _XCCurrentVersionName'`
# Mogenerator Location
if [ -x /usr/local/bin/mogenerator ]; then
echo "mogenerator exists in /usr/local/bin path";
MOGENERATOR_DIR="/usr/local/bin";
elif [ -x /usr/bin/mogenerator ]; then
echo "mogenerator exists in /usr/bin path";
MOGENERATOR_DIR="/usr/bin";
else
echo "mogenerator not found"; exit 1;
fi
$MOGENERATOR_DIR/mogenerator --model "$DATA_MODEL_PACKAGE/$CURRENT_VERSION" --output-dir "$MODELS_DIR/"
Add options to mogenerator as appropriate. --base-class <your base class> and --template-var arc=true are common.
Random tip. If you get Illegal Instruction: 4 when you run mogenerator. Install it from the command line:
$ brew update && brew upgrade mogenerator

Resources