Service workers with non git-committed global variables - service-worker

In the script below I am hard-coding a firebase variable that I'd rather not commit to my repo. My firebase values are all in a single file and the rest of my javascript imports those using ES6 modules (and webpack). But how should I access that data from this service worker file
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the config.messagingSenderId.
firebase.initializeApp({
'messagingSenderId': "8033333334"
});
// firebase.initializeApp({
// 'messagingSenderId': config.messagingSenderId
// });

Any scripts that you reference via importScripts() will execute synchronously in the same ServiceWorkerGlobalScope as your main service worker file. That means that they share the same self global, and you know that after the importScripts() completes, they will have fully executed.
So if you had a script called bootstrap.js, and it contained
self.config = self.config || {};
self.config.messagingSenderId = 'my_sender_id';
then you could do the following in your service-worker.js:
importScripts(
'bootstrap.js',
'https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js',
'https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js'
);
firebase.initializeApp({
'messagingSenderId': self.config.messagingSenderId
});
It's up to you whether you check in bootstrap.js to source control, whether you generate it on the fly during build time, etc.

Related

Failures in init.groovy.d scripts: null values returned

I'm trying to get Jenkins set up, with configuration, within a Docker environment. Per a variety of sources, it appears the suggested method is to insert scripts into JENKINS_HOME/init.groovy.d. I've taken scripts from places like the Jenkins wiki and made slight changes. They're only partially working. Here is one of them:
import java.util.logging.ConsoleHandler
import java.util.logging.FileHandler
import java.util.logging.SimpleFormatter
import java.util.logging.LogManager
import jenkins.model.Jenkins
// Log into a file
println("extralogging.groovy")
def RunLogger = LogManager.getLogManager().getLogger("hudson.model.Run")
def logsDir = new File("/var/log/jenkins")
if (!logsDir.exists()) { logsDir.mkdirs() }
FileHandler handler = new FileHandler(logsDir.absolutePath+"/jenkins-%g.log", 1024 * 1024, 10, true);
handler.setFormatter(new SimpleFormatter());
RunLogger.addHandler(handler)
This script fails on the last line, RunLogger.addHandler(handler).
2019-12-20 19:25:18.231+0000 [id=30] WARNING j.util.groovy.GroovyHookScript#execute: Failed to run script file:/var/lib/jenkins/init.groovy.d/02-extralogging.groovy
java.lang.NullPointerException: Cannot invoke method addHandler() on null object
I've had a number of other scripts return NULL objects from various gets similar to this one:
def RunLogger = LogManager.getLogManager().getLogger("hudson.model.Run")
My goal is to be able to develop (locally) a Jenkins implementation and then hand it to our sysops guys. Later, as I add pipelines and what not, I'd like to be able to also work on them in a local Jenkins configuration and then hand something for import into production Jenkins.
I'm not sure how to produce API documentation so I can chase this myself. Maybe I need to stop doing it this way and just grab the files that get modified when I do this via the GUI and just stuff the files into the right place.
Suggestions?

Window Duration within PipelineOptions in Cloud Dataflow

Been trying to dig how I could do this but I'm constantly getting the same error, which is the following...
An exception occured while executing the Java class. Value only available at runtime, but accessed from a non-runtime context:
Solved this issue before accessing .get() once the Pipeline was instantiated and configured, inside a custom DoFn that was needed.
My problem now is when defining the Duration of a Window within the Pipeline, which isn't a custom object such as the previously metioned one.
#Description("Defaults to 5 (minutes).")
#Default.Long(5)
ValueProvider<Long> getWindowDuration();
I can't wrap my head around how to access that value once the Pipeline has been deployed, or if the current Window objects support PipelineOptions in some of its constructors...
.apply(
options.getWindowDuration() + "min Window",
Window.<GenericRecord>into(
FixedWindows.of(
Duration.standardMinutes(options.getWindowDuration().get())
/** [Hardcoded so I can debug] Duration.standardMinutes(5) **/))
.triggering(AfterProcessingTime.pastFirstElementInPane()
(...)
Window duration has to be specified when defining the pipeline (not during execution). So you should set it directly in the window object (for example, FixedWindows). The value you set does not necessarily have to come from a pipeline option.

Using jenkins docker image

I am preparing and docker image based on jenkins:lts. To setup the initial configuration I use the init.groovy.d scripts, but:
is that the best option?
is there a way to prevent those scripts to run again in the second start? (I do not want to overwrite any change after init)
I end up using a file as a status marker
// Skip exec. if the init already run once, do not overwrite ui config
final File status = new
File("${System.getenv("JENKINS_HOME")}/init.groovy.d/uk-config.status")
if (status.exists()) {
logger.info("First init already run")
return
}
status.createNewFile()
It creates a file the first time the script runs and it checks if the file exists and prevent execution the second one.

How can I make a firefox add-on contentscript inject and run a script before other page scripts?

I'm working on a Browser extension/add-on. We have it working in Chrome, so I'm trying to get it working in Firefox.
I've gotten my add-on to load in Firefox Developer Edition 49.0a2 (2016-07-25).
My extension involves a content_script set to run_at: document_start, so it can inject a script tag before other page scripts run, so it can make an object globally available to websites.
This has seemed to work fine in Chrome, but in Firefox it has proven to be a bit of a race condition, with other page resources loading first most of the time.
Is there a strategy to load a content script in a way that it can inject & load a script before any other page scripts run?
When I add logs, I can isolate what is happening pretty nicely. In this example content-script:
// inject in-page script
console.log('STEP 1, this always happens first')
var scriptTag = document.createElement('script')
scriptTag.src = chrome.extension.getURL('scripts/inpage.js')
scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement
// append as first child
container.insertBefore(scriptTag, container.children[0])
Now if the file scripts/inpage.js simply runs a log, like
console.log('STEP 2, this should always run second')
And I visit a page with a script like this:
console.log('Step 3, the page itself, should run last')
In practice, Step 2 and Step 3 run in a non-deterministic order.
Thanks a lot!
I have Firefox-compatible version of the script in a public repository on a special branch if you dare to try it yourself: https://github.com/MetaMask/metamask-plugin/tree/FirefoxCompatibility
An dynamically inserted script with an external source (<script src>) does not block the execution of scripts, so there is no guarantee that your script would load. If your extension worked in Chrome, it was just by sheer luck.
If you really want to run some script before the rest, you have to run it inline:
var actualCode = `
// Content of scripts/inpage.js here
`;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
Ideally, your build script would read scripts/inpage.js, serialize it to a string and put it in the actualCode variable. But if inpage.js is just a few lines of code, then the above can be used.
Note that you should not inject code in the web page unless it is absolutely necessary. The reason for that is that the execution environment of the page is untrusted. If you inject at document_start, then you can save functions and (prototype) methods that use for later (in a closure), but very careful coding is required.
If your content script is not generated by a build script and you still want to keep the scripts separate, then you can also use synchronous XMLHttpRequest to fetch the script. Synchronous XHR is deprecated for performance reasons, so use it at your own risk. Extension code is typically bundled with your extension, so the use of sync xhr should be low-risk:
// Note: do not use synchronous XHR in production!
var x = new XMLHttpRequest();
x.open('GET', chrome.runtime.getURL('scripts/inpage.js'), false);
x.send();
var actualCode = x.responseText;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
If you are using a bootstrap.js based addon you can use a framescript and DOMWindowCreated to work with the document before even the HTML DOM (past basics of document.body etc) renders - https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment#Events - the innerHTML will be available but no script would have executed. You can put your inline script at the top as #Rob mentioned.

Windows service runs file locally but not on server

I created a simple Windows service in dot net which runs a file. When I run the service locally I see the file running in the task manager just fine. However, when I run the service on the server it won't run the file. I've checked the path to the file which is fine. Below is the code used to launch the process which runs the file. Any ideas?
protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
eventLog1.WriteEntry("VirtualCameraService started");
// Create An instance of the Process class responsible for starting the newly process.
System.Diagnostics.Process process1 = new System.Diagnostics.Process();
// Set the directory where the file resides
process1.StartInfo.WorkingDirectory = "C:\\VirtualCameraServiceSetup\\";
// Set the filename name of the file to be opened
process1.StartInfo.FileName = "VirtualCameraServiceProject.avc";
// Start the process
process1.Start();
}
My first instinct is to check permissions.
Is the file extension registered on the server? It could be that the server is failing to find an action associated with .avc. You might want to move this to ServerFault since it is most likely a configuration or Windows OS version difference.
You may want to put a try catch block in that method and write out any exception to the event log, this should piont you in the write direction.
But as D.Shawley said it sounds like a config issue.
Ok, once again the problem was that the file wasn't associated to the program on the server. So instead of trying to open the file I needed to open the program to run the file, then pass the file as an argument to the program. Below is the syntax.
// Set the directory where the file resides
process1.StartInfo.WorkingDirectory = "C:\\Program Files (x86)\\Axis Communications\\AXIS Virtual Camera 3\\";
// Set the filename name of the file to be opened
//process1.StartInfo.FileName = "VirtualCamera.exe C:\\VirtualCameraServiceSetup\\VirtualCameraServiceProject.avc";
process1.StartInfo.FileName = "VirtualCamera.exe";
process1.StartInfo.Arguments = "VirtualCameraServiceProject.avc";

Resources