in Jenkins Windows ~ read.

Semi-automatic Jenkins upgrade on Windows

Jenkins offers nice auto-update functionality, where it will download new version, schedules a restart and updates. But what to do when it is unable to download the version?

In our company there is this really annoying proxy antivirus scanner, that likes to inspect all jar and war files for viruses, so things like Wildfly or Netbeans take hours to download. That’s really bad new when one wants to update Jenkins, as it will time out after minute or two.

The usual approach I take for plugins that fail to download, is that I download them manually (e. g. by replacing http with https in the mirror link, then the antivirus is bypassed ;)) and upload them into Jenkins. This doesn’t work for the main war file, of course.

Should I’ve been running on Linux, I would just download the file, and overwrite existing file. I’m on Windows and the process have the file locked. I would really like just to trigger this logic for upgrading the file at startup.

To find out how that works I looked into Jenkins' WindowsLifecycleService:

    /**
     * On Windows, jenkins.war is locked, so we place a new version under a special name,
     * which is picked up by the service wrapper upon restart.
     */
    @Override
    public void rewriteHudsonWar(File by) throws IOException {
        File dest = getHudsonWar();
        // this should be impossible given the canRewriteHudsonWar method,
        // but let's be defensive
        if(dest==null)  throw new IOException("jenkins.war location is not known.");

        // backing up the old jenkins.war before its lost due to upgrading
        // unless we are trying to rewrite jenkins.war by a backup itself
        File bak = new File(dest.getPath() + ".bak");
        if (!by.equals(bak))
            FileUtils.copyFile(dest, bak);

        String baseName = dest.getName();
        baseName = baseName.substring(0,baseName.indexOf('.'));

        File baseDir = getBaseDir();
        File copyFiles = new File(baseDir,baseName+".copies");

        try (FileWriter w = new FileWriter(copyFiles, true)) {
            w.write(by.getAbsolutePath() + '>' + getHudsonWar().getAbsolutePath() + '\n');
        }
    }

So I did the same thing manually:

  1. Downloaded new war file to d:\temp

  2. Created file jenkins.copies in jenkins' home with content

    d:/temp/jenkins.war>d:/jenkins/jenkins.war

    I saved it with UNIX line endings and verified, that there is indeed just single \n at the end (service will fail to start if that is not the case).

  3. Had jenkins restart once it is idle

  4. DONE. Jenkins did update just as if it had downloaded the file itself.

I kept the .copies file handy for future updates. I will just put new version in temp and copy the .copies file over.

comments powered by Disqus