Related
Here is the folder structure I have.
Workspace folder: D:\Node\MyNode\
When Jenkins build runs on a node, the files from scm gets downloaded to the following folder: D:\Node\MyNode\xx_development
I need to do cd to the folder "xx_development" and this name xx can change for different strasms (RTC) but "_development" remains same.
how can I do cd to a folder with (*development) using a pipeline script?
Edit: I am using windows Nodes for Jenkins.
To change the current directory to the folder with the pattern *_development, you can use the following script:
For Windows:
def folder = bat(returnStdout: true, script: 'dir /b /ad | findstr "_development"').trim()
bat "cd ${folder}"
dir /b /ad | findstr "_development" --> lists all directories in the current folder and filters them by the pattern _development.
/b --> to list only the directory names.
/ad --> to list only directories.
findstr --> to filter the output by the pattern _development.
The second line changes the current directory to the directory stored in the Folder variable.
For Linux:
def Folder = sh(returnStdout: true, script: 'ls -d */ | grep "_development"').trim()
sh "cd ${Folder}"
ls -d */ | grep "_development" --> lists all directories in the folder and filters by the pattern _development.
trim() --> If there are any leading or trailing whitespaces, they are removed using this command.
The second line changes the current directory to the folder stored in the Folder variable.
I have a Jenkinsfile that uses the shared Jenkins lib and calls method inside the groovy file defined below.
shared-jenkins-lib
|
|-----------vars
| |-------pipeline_script.groovy
|
|-----------scripts
|-------test_script.groovy
This is the structure of the library and pipeline_script.groovy has a method test which is called from jenkinsfile.
def test(){
dockerArgs = "--entrypoint /bin/bash"
dockerCommand = "`../scripts/test_script.sh`"
dockerOut = sh (script: "docker run ${dockerArgs} ${image} ${dockerCommand}", returnStatus: true)
}
I refer test_script.sh but doesn't seem to find the file in that location.
I am running jenkins within docker. What is the correct way to refer to the script
As stated in the docs of the shared libraries plugin, a library repo has a very specific structure. The root of the repo can have the following 3 folders:
+- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
+- vars
| +- foo.groovy # for global 'foo' variable
| +- foo.txt # help for 'foo' variable
+- resources # resource files (external libraries only)
| +- org
| +- foo
| +- bar.json # static helper data for org.foo.Bar
If you want to refer to a helper code/data from your library method, you should put it in the resources directory, and then you can retrieve it with the libraryResource step, also described in the docs.
You need to pass in the workflowscript object into test().
def test(workFlowScript wfs) {
...
wfs.sh ''
wfs.echo ''
wfs.withCredentials()
}
// your Jenkisnfile which call test()
test(this) // this is the instance of workFlowScript
I have a directory like this:
assigment
|
|__ src
| |
| |__ Main.scala
|
|
|__ testcase
|
|__ Simple.in
In Main.scala, Simple.in is read by Source.fromFile():
val inputFile = "Simple.in"
val lines = Source.fromFile("./testcase/" + inputFile).getLines
But when I run Main.scala in sbt the FileNoutFoundException appear. When I change the path to "../testcase/" + inputFile then it works fine. The original path is from my teacher, so I wonder which path is actually correct? Oh, I'm using Linux btw...
./ means: the current path
../ means: the directory "above" the current directory
Thus: when you run your Scala class from "src", "./testcase" makes it look for a directory testcase within "src"; or using full path names:
"assignment/src/" + "./testcase" turns into "assignment/src/testcase"
Whereas, when you use
"assignment/src/" + "../testcase" turns into "assignment/testcase"
therefore, the version with ".." finds the valid path. That is all the magic here!
. => current dir
.. => one above curren dir
But standard way to access resources is using the resources folder of sbt project structure.
This way helps you to access files independent of where (which class) you are accessing the resource in the code.
Folder to put your files
src/main/resources
val stream : InputStream = getClass.getResourceAsStream("/readme.txt")
val lines = scala.io.Source.fromInputStream( stream ).getLines
TLDR;
When starting erlang node (using just erl command for an instance), how could I force it not to use local OTP libraries and get code:get_path() empty?
Rationale.
I want to touch erl_boot_server. Don't doing something certain, just playing. I have built sample release and want to load it via network. Here is it.
[vkovalev#t30nix foobar]$ tree -L 2
.
|-- bin
| |-- foobar
| |-- foobar-0.0.0+build.1.ref307ae38
| |-- install_upgrade.escript
| |-- nodetool
| `-- start_clean.boot
|-- erts-6.1
| |-- bin
| |-- doc
| |-- include
| |-- lib
| |-- man
| `-- src
|-- lib
| |-- foobar-0.1.0
| |-- kernel-3.0.1
| |-- sasl-2.4
| `-- stdlib-2.1
`-- releases
|-- 0.0.0+build.1.ref307ae38
|-- RELEASES
`-- start_erl.data
First I start boot node.
[vkovalev#t30nix foobar]$ erl -sname boot -pa lib/*/ebin -pa releases/0.0.0+build.1.ref307ae38/ -s erl_boot_server start localhost
(boot#t30nix)1> {ok, _, _} = erl_prim_loader:get_file("foobar.boot").
(boot#t30nix)2> {ok, _, _} = erl_prim_loader:get_file("foobar_app.beam").
As you can see, all okay here. Then I start slave node:
[vkovalev#t30nix ~]$ erl -sname slave -loader inet -hosts 127.0.0.1 -boot foobar
{"init terminating in do_boot",{'cannot get bootfile','foobar.boot'}}
Crash dump was written to: erl_crash.dump
init terminating in do_boot ()
I dug into erl_prim_loader and found that stuff. One clause acts when Paths is empty (it just forward requested filename to boot server as is), another acts when Paths is non-empty. In this case (I wonder why) prim loader cripples requested file name with its own (clientside) paths and then ask SERVER to serve this path. In my understanding this is quite weird thing, but okay. Then I checked code:get_path() on slave node, and yes, it has paths to local otp installation.
So, returning to subject. How could I force slave node not to use any local OTP installation (if it already presents)?
UPD: Added more investigation results.
First thing -
https://github.com/erlang/otp/blob/maint/erts/preloaded/src/erl_prim_loader.erl#L669.
erl_prim_loader (in inet mode) for some (unclear for me) reasons tries
to cripple any requested module with local (clientside) paths.
It seems there is no way to force loader on slave node to keep its
paths empty: https://github.com/erlang/otp/blob/maint/erts/preloaded/src/init.erl#L697
Paths in my bootscript looks like
{path,["$ROOT/lib/kernel-4.0/ebin","$ROOT/lib/stdlib-2.5/ebin"]}, so
it seems, if I'll get bootscript loaded, anyway, I won't be able boot
system with it.
What's going on? Is erlang network boot feature broken? Or just my
brains? How could I get node successfully network-booted?
Do you think node of slave type is just named by "slave"?
The following code from the project tsung, file named "ts_os_mon_erlang.erl".
start_beam(Host) ->
Args = ts_utils:erl_system_args(),
?LOGF("Starting os_mon beam on host ~p ~n", [Host], ?NOTICE),
?LOGF("~p Args: ~p~n", [Host, Args], ?DEB),
slave:start(list_to_atom(Host), ?NODE, Args).
In additon, the slave module restriction as follows:
Slave nodes on other hosts than the current one are started with the program rsh. The user must be allowed to rsh to the remote hosts without being prompted for a password. This can be arranged in a number of ways (refer to the rsh documentation for details). A slave node started on the same host as the master inherits certain environment values from the master, such as the current directory and the environment variables. For what can be assumed about the environment when a slave is started on another host, read the documentation for the rsh program.
An alternative to the rsh program can be specified on the command line to erl as follows: -rsh Program.
The slave node should use the same file system at the master. At least, Erlang/OTP should be installed in the same place on both computers and the same version of Erlang should be used.
If you want to start a node with different path, I think you could do it by script with differnt environment variable, for master node, not slave node.
I think rebar project's can help for the similiar purpose. It include how to manipulate the path:
From rebar_core.erl file:
process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
{DirModules, ModuleSetFile}) ->
Config0 = rebar_config:set(Config, current_command, Command),
%% Get the list of modules for "any dir". This is a catch-all list
%% of modules that are processed in addition to modules associated
%% with this directory type. These any_dir modules are processed
%% FIRST.
{ok, AnyDirModules} = application:get_env(rebar, any_dir_modules),
Modules = AnyDirModules ++ DirModules,
%% Invoke 'preprocess' on the modules -- this yields a list of other
%% directories that should be processed _before_ the current one.
{Config1, Predirs} = acc_modules(Modules, preprocess, Config0,
ModuleSetFile),
%% Remember associated pre-dirs (used for plugin lookup)
PredirsAssoc = remember_cwd_predirs(Dir, Predirs),
%% Get the list of plug-in modules from rebar.config. These
%% modules may participate in preprocess and postprocess.
{ok, PluginModules} = plugin_modules(Config1, PredirsAssoc),
{Config2, PluginPredirs} = acc_modules(PluginModules, preprocess,
Config1, ModuleSetFile),
AllPredirs = Predirs ++ PluginPredirs,
?DEBUG("Predirs: ~p\n", [AllPredirs]),
{Config3, DirSet2} = process_each(AllPredirs, Command, Config2,
ModuleSetFile, DirSet),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
ok = file:set_cwd(Dir),
%% Check that this directory is not on the skip list
Config7 = case rebar_config:is_skip_dir(Config3, Dir) of
true ->
%% Do not execute the command on the directory, as some
%% module has requested a skip on it.
?INFO("Skipping ~s in ~s\n", [Command, Dir]),
Config3;
false ->
%% Check for and get command specific environments
{Config4, Env} = setup_envs(Config3, Modules),
%% Execute any before_command plugins on this directory
Config5 = execute_pre(Command, PluginModules,
Config4, ModuleSetFile, Env),
%% Execute the current command on this directory
Config6 = execute(Command, Modules ++ PluginModules,
Config5, ModuleSetFile, Env),
%% Execute any after_command plugins on this directory
execute_post(Command, PluginModules,
Config6, ModuleSetFile, Env)
end,
%% Mark the current directory as processed
DirSet3 = sets:add_element(Dir, DirSet2),
%% Invoke 'postprocess' on the modules. This yields a list of other
%% directories that should be processed _after_ the current one.
{Config8, Postdirs} = acc_modules(Modules ++ PluginModules, postprocess,
Config7, ModuleSetFile),
?DEBUG("Postdirs: ~p\n", [Postdirs]),
Res = process_each(Postdirs, Command, Config8,
ModuleSetFile, DirSet3),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
ok = file:set_cwd(Dir),
%% Once we're all done processing, reset the code path to whatever
%% the parent initialized it to
restore_code_path(CurrentCodePath),
%% Return the updated {config, dirset} as result
Res.
restore_code_path(no_change) ->
ok;
restore_code_path({added, Paths}) ->
%% Verify that all of the paths still exist -- some dynamically
%% added paths can get blown away during clean.
[code:del_path(F) || F <- Paths, erl_prim_loader_is_file(F)],
ok.
erl_prim_loader_is_file(File) ->
erl_prim_loader:read_file_info(File) =/= error.
Make sure you use the -setcookie option. From the erl -man erl page:
-loader Loader:
Specifies the method used by erl_prim_loader to
load Erlang modules in to the system. See
erl_prim_loader(3). Two Loader methods are supported,
efile and inet. efile means use the local file
system, this is the default. inet means use a boot
server on another machine, and the -id, -hosts and
-setcookie flags must be specified as well. If Loader
is something else, the user supplied Loader port
program is started.
I would like to pack my firefox extension as xpi file. I tried by adding it to archive and name it as filename.xpi
But when i try to install it on firefox am getting "package corrupted" message. Is there any way i can create a valid xpi file ?
I have installed cygwin and tried to execute zip command to create xpi file. But got zip is not a command error.
Can somebody guide me to get it done ?
If you are on windows (to install cygwin it looks like you do), you can use the windows built in tool:
Select the contents of the extension (remember, don't select the outside folder).
Right Click
Send to
Compressed (zipped) folder
Then just replace the .zip for .xpi in the filename
Looks like your problem is on completing the point 1. correctly. Select only the contents of the extension. Not the folder that contains it.
So basically your zip file should have following structure:
my_extension.zip
|- install.rdf
|- chrome.manifest
|- <chrome>
and NOT this structure:
my_extension.zip
|- <my_extension>
|- install.rdf
|- chrome.manifest
|- <chrome>
I experienced the same problems today and found the error to be that the add-on was obviously not signed by Mozilla, causing Firefox to refuse the installation. Up until recently, it was possible to by-pass this security check by setting xpinstall.signatures.required to false in about:config. However, as of Firefox 46, signing is mandatory and no by-pass is provided any longer, see https://blog.mozilla.org/addons/2016/01/22/add-on-signing-update/ This means that one has to either downgrade to a previous version or use a non release channel version to test one's addons :(
Also, here's how I pack an extension for Firefox with command line 7z:
cd /the/extension/folder/
7z a ../<extension_name>.xpi * -r
(where 'a' stands for "add/create" and "-r" for recursive)
Or to update the extension with the file(s) we just edited:
cd /the/extension/folder/
7z u ../<extension_name>.xpi * -r
("u" for update the archive's content)
Two methods, using the GUI 7zFM.exe, or a command line or batch file.
1.0) GUI method. Assuming 7-Zip is installed with shell integration so you see 7-Zip show up in the context-menu (right-click of selected files) of Windows Explorer.
1.a) Go into the folder of your add-on.
1.b) Select all the files and folders you want to include in the .xpi. Assuming you don't have any files you want to ignore down in any sub-folders. If you do, you might want to use the command line option.
1.c) Right-click on the list of selected files, find the 7z icon, choose the Add to archive... option.
1.d) A dialog pops up. Edit the location and name of the zip file, change to .zip to .xpi, etc.
1.e) Note if you create the .xpi in the same folder, don't re-archive it in the future, as your add-on will fail horribly. You never want an .xpi ending up inside your .xpi by accident. I usually just create it in the parent folder, by adding ..\ to the beginning of the file name, e.g. ..\addon-1.2.3-fx.xpi
1.f) 7-Zip has a lot of powerful compression options, not all of which Firefox can handle. Choose settings which Firefox is able to process. Refer to image.
2.0) Command Line method. Assuming you're in Windows, and know how to open a command prompt, change drives and directories (a.k.a. folders).
2.a) CD to your add-on directory.
2.b) Use the most basic 7-Zip command line.
"C:\Program Files\7-Zip\7z.exe" a -tzip addon-1.2.3-fx.xpi *
2.c) You can get a smaller file by finding the exact command line options which correspond to the above GUI, namely:
"C:\Program Files\7-Zip\7z.exe" a -tzip -mx=9 -mm=Deflate -mfb=258 -mmt=8 "addon-1.2.3-fx.xpi" *
Note that there is no Dictionary size = 32kb option when using Deflate Compression method. Otherwise, the options are in order and correspond to the GUI.
|-----------------------|---------|--------------|
| Option / Parameter | GUI | Command line |
|-----------------------|---------|--------------|
| Archive format | zip | -tzip |
| Compression level | Ultra | -mx=9 |
| Compression method | Deflate | -mm=Deflate |
| Dictionary size | 32 KB | (none) |
| Word size | 258 | -mfb=258 |
| Number of CPU threads | 8 | -mmt=8 |
|-----------------------|---------|--------------|
| Additional Parameters | | |
|-----------------------|---------|--------------|
| Recurse into Folders | (none) | -r |
| Multiple passes | (none) | -mpass=15 |
| Preserve Timestamps | (none) | -mtc=on |
| Ignore files in list | | -x#{ignore} |
|-----------------------|---------|--------------|
Notes:
i) The multi-thread option (-mmt=8) is specific to my system which has 8 cores. You will need to lower this to 6 or 4 or 2 or 1 (i.e. remove option) if you have fewer cores, etc, or increase if you have more. Won't make much difference either way for a small extension.
ii) The option to recurse into folder may or may not be the default, so specifying this option should ensure proper recursion.
iii) The option to preserve windows timestamps (creation, access, modification) should default to on anyways, so may not be needed.
iv) The ignore files in list option is any file which has a list of files and wildcards of files you wish to exclude.
2.d) Advanced topic #1: ignore file list (examples)
|----------------|------------------------------------|
| What to Ignore | Why to Ignore |
|----------------|------------------------------------|
| TODO.txt | Informal reminders of code to fix. |
| *.xpi | In case you forget warning above! |
| .ignore | Ignore the ignore file list. |
| ignore.txt | Same thing, if you used this name. |
|----------------|------------------------------------|
"C:\Program Files\7-Zip\7z.exe" a -tzip -mx9 -mm=Deflate -mfb=258 -mmt=8 -mpass=15 -mtc=on "addon-1.2.3-fx.xpi" * -x#ignore.txt
2.e) Advanced topic #2: Batch file (Windows CMD.EXE), assuming fairly recent windows, i.e. from the 21st century. This can be as simple and rigid, or complex and flexible as you care to make it. A general balance is to assume you will be in the Command Prompt, in the top level directory of the add-on you are working on, and that you have intelligently named that directory to have the same basename of the .xpi file e.g. D:\dev\addon-1.2.3-fx directory for the addon-1.2.3-fx.xpi add-on xpi. This batch file makes this assumption, and dynamically figures out the correct basename to use for the .xpi.
#ECHO OFF
REM - xpi.bat - batch file to create Mozilla add-on xpi using 7-Zip
REM - This finds the folder name, and discards the rest of the full path, saves in an environment variable.
FOR %%* IN (.) DO SET XPI=%%~nx*
REM - Uncomment the DEL line, or delete .xpi file manually, if it gets corrupted or includes some other junk by accident.
REM DEL "%XPI%.xpi"
REM - Command line which does everything the GUI does, but also lets you run several passes for the smallest .xpi possible.
"C:\Program Files\7-Zip\7z.exe" a -tzip -r -mx=9 -mm=Deflate -mfb=258 -mmt=8 -mpass=15 -mtc=on "%XPI%.xpi" * -x#ignore.txt
REM - Cleanup the environment variable.
SET XPI=
When pack extension using 7z, compress into .zip and then rename to .xpi, dont compress i
Do as per the following while using 7z
Select only the inner contents and not the outer folder.
Enter the filename as filename.xpi and choose archive format as zip in the prompt that appears while zipping.
You will find a valid xpi file created.
Use the created xpi for installing your extension on firefox.
It works!
Just zip all the files and folders inside my_extension folder and change the resulting zipped file's extension to my_extension.xpi
/my_extension
|- defaults/
|- locale/
|- resources/
|- install.rdf
|- ... (other files and folders)
Installation of xpi file created from zipped file of my_extension folder will result error as
"This add-on could not be installed because it appears to be corrupt." error
I try myself to build a zip in several ways because I was convinced I do something wrong 'cause all i got was "package corrupted" stuff .
well.. not anymore and I do not even need to load it from Load temporary add-on (now i drag and drop the xpi file from the desktop over Waterfox and I install it as legit xpi file!
How I do that?
'Cause I try myself the github stuff I load it first in Load temporary add-on (url:about:debugging#addons) the xpi file using the method used by user314159 with the .bat file method that use 7zip.
after you load that you should read somewhere something similar to:
Extension ID
86257e65ca311ee368ffcee50598ce25733a049b#temporary-addon
then all you should do is add inside manifest.json modifying the "applications" :
"applications": {
"gecko": {
"strict_min_version": "54.0a1",
"id": "86257e65ca311ee368ffcee50598ce25733a049b#temporary-addon"
}
},
after this push Remove to uninstall the temporary addon then you should build the xpi again like you did before
now is a normal xpi file SIGNED what you can install normal ! (here is works without modifying anything else)
I use Waterfox x64 i's seems to be problems to Firefox
the answer is you should upload your extension on the hub then to use mozilla signing api
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Distribution
Create file config.js
Insert code into config.js
//
try {
Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
.eval("SIGNED_TYPES.clear()");
}
catch(ex) {}
Move config.js to application work folder, eg: C:\Program Files\Mozilla Firefox\
Create config-prefs.js and write code into:
pref("general.config.obscure_value", 0);
pref("general.config.filename", "config.js");
Place config-pres.js to C:\Program Files\Mozilla Firefox\defaults\pref\
Restart Firefox
Look result