Skip to content

Instantly share code, notes, and snippets.

@balajeerc
Last active January 3, 2016 18:08
Show Gist options
  • Select an option

  • Save balajeerc/29d731a5c0686eb53bf6 to your computer and use it in GitHub Desktop.

Select an option

Save balajeerc/29d731a5c0686eb53bf6 to your computer and use it in GitHub Desktop.

Revisions

  1. balajeerc revised this gist Jan 3, 2016. 1 changed file with 6 additions and 5 deletions.
    11 changes: 6 additions & 5 deletions copy_yum_repo.js
    Original file line number Diff line number Diff line change
    @@ -3,21 +3,22 @@

    "use strict";

    /**
    /*
    * Copies over the files from an installed yum package into a specified folder
    * along with the files of all its dependency packages
    *
    * Requirements:
    * nodejs (0.10.x and above) (sudo yum install nodejs)
    * repoquery (sudo yum install rpm-utils)
    * repoquery (sudo yum install yum-utils)
    * npm (sudo yum install npm)
    * Nodejs dependencies:
    * fs-extra (npm install --save fs-extra)
    * async (npm install --save fs-extra
    * WARNING: THIS WILL COPY ALL DEPENDENCIES, including packages like bash, vim etc
    * which is most often NOT something you'd want. To prevent this from happening, specify
    *
    * Warning: THIS WILL COPY ALL DEPENDENCIES, including packages like bash, vim etc.
    * which is most often NOT something you would want. To prevent this from happening, specify
    * an optional argument (see excluded_package_list below) containing a line separated list
    * of packages you need ignored.
    * of packages you need ignored.
    *
    * Usage: copy_yum_repo <package_name> <path_to_folder> [excluded_package_list]
    * where:
  2. balajeerc revised this gist Jan 3, 2016. No changes.
  3. balajeerc revised this gist Jan 3, 2016. 1 changed file with 6 additions and 8 deletions.
    14 changes: 6 additions & 8 deletions copy_yum_repo.js
    Original file line number Diff line number Diff line change
    @@ -8,14 +8,12 @@
    * along with the files of all its dependency packages
    *
    * Requirements:
    * 1) nodejs (0.10.x and above) (sudo yum install nodejs)
    * 2) repoquery (sudo yum install rpm-utils)
    * 3) npm (sudo yum install npm)
    * 4) Nodejs dependencies:
    * i) fs-extra (npm install --save fs-extra)
    * ii) async (npm install --save fs-extra)
    *
    *
    * nodejs (0.10.x and above) (sudo yum install nodejs)
    * repoquery (sudo yum install rpm-utils)
    * npm (sudo yum install npm)
    * Nodejs dependencies:
    * fs-extra (npm install --save fs-extra)
    * async (npm install --save fs-extra
    * WARNING: THIS WILL COPY ALL DEPENDENCIES, including packages like bash, vim etc
    * which is most often NOT something you'd want. To prevent this from happening, specify
    * an optional argument (see excluded_package_list below) containing a line separated list
  4. balajeerc created this gist Jan 3, 2016.
    219 changes: 219 additions & 0 deletions copy_yum_repo.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,219 @@
    #!/bin/sh
    ':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

    "use strict";

    /**
    * Copies over the files from an installed yum package into a specified folder
    * along with the files of all its dependency packages
    *
    * Requirements:
    * 1) nodejs (0.10.x and above) (sudo yum install nodejs)
    * 2) repoquery (sudo yum install rpm-utils)
    * 3) npm (sudo yum install npm)
    * 4) Nodejs dependencies:
    * i) fs-extra (npm install --save fs-extra)
    * ii) async (npm install --save fs-extra)
    *
    *
    * WARNING: THIS WILL COPY ALL DEPENDENCIES, including packages like bash, vim etc
    * which is most often NOT something you'd want. To prevent this from happening, specify
    * an optional argument (see excluded_package_list below) containing a line separated list
    * of packages you need ignored.
    *
    * Usage: copy_yum_repo <package_name> <path_to_folder> [excluded_package_list]
    * where:
    * package_name -- (required) name of package you want to copy over
    * destination_folder -- (required) path to destination folder where the files need to be copied over
    * excluded_package_list -- (optional but highly recommended) path to a file containing a line separated
    * list of packages to ignore during copy (possibly like bash, glibc etc.)
    */
    var fs = require('fs-extra');
    var child_process = require('child_process');
    var async = require('async');
    var path = require('path');
    async.waterfall([
    function (callback) {
    // Argument parsing and initialization
    var errrorMsg;
    // Fetch commandline arguments
    if (process.argv.length < 4){
    errrorMsg = "Usage: copy_yum_repo <package_name> <path_to_folder> [excluded_package_list]";
    callback(errrorMsg, null);
    }
    // If we got here then commandline args are fine
    // Proceed by passing that to the next step
    callback(null, process.argv);
    },
    function (commandlineArgs, callback) {
    // We next open the file containing list of packages already
    // found in RHEL minimal and extract the package names
    var excludedPackages = {};
    var errorMsg;
    if (commandlineArgs.length == 5) {
    console.log("Parsing excluded packages listed in: " + commandlineArgs[4]);
    try {
    fs.readFile(commandlineArgs[4], function (err, data) {
    data.toString().split('\n').forEach( function (line) {
    var packageDetails, packageName;
    packageDetails = line.split(/\s+/);
    packageName = packageDetails[0];
    if (packageName.length != 0) {
    excludedPackages[packageName] = true;
    }
    });
    });
    // Move on to the next phase
    callback(null, commandlineArgs, excludedPackages);
    } catch (e) {
    errorMsg = "Unable to open excluded package list: \n" + e;
    callback(errorMsg, null);
    }
    }
    },
    function (commandlineArgs, excludedPackages, callback) {
    // We find the dependencies of the given package by running 'repoquery --requires --recursive --resolve <libname>'
    console.log("Querying dependencies of: " + process.argv[2]);
    var dependencyQueryHandler = {
    output: '',
    dependencies: {},
    onOutput: function (output) {
    this.output += output;
    },
    onError: function (errorInfo) {
    },
    onComplete: function () {
    // We can now process the dependencies
    var self = this;
    var outputLines = this.output.split('\n').forEach(function (line) {
    var re = /^(.*)-.*:.*.x86_64/;
    var regexResults = line.match(re);
    var dependencyName;
    if(regexResults){
    dependencyName = regexResults[1];
    // Check if this is one of the excluded packages
    if (!(dependencyName in excludedPackages)) {
    self.dependencies[dependencyName] = true;
    }
    }
    });
    // Note that the main library whose dependencies we have listed
    // also needs to have its files copied over
    self.dependencies[process.argv[2]] = true;
    callback(null, commandlineArgs, self.dependencies);
    }
    };
    try {
    // repoquery --requires --recursive --resolve
    var deplistOut = child_process.spawn('repoquery', ['--requires', '--recursive', '--resolve', process.argv[2]]);
    deplistOut.stdout.on('data', function (data) {
    dependencyQueryHandler.onOutput(data);
    });
    deplistOut.on('close', function (errCode) {
    dependencyQueryHandler.onComplete();
    });
    deplistOut.stderr.on('data', function (error) {
    dependencyQueryHandler.onError(error);
    });
    } catch (e) {
    callback("Unable to do repoquery: " + e, null);
    }
    },
    function (commandlineArgs, dependencies, callback){
    // Here we process the files in each package and copy them over
    // to the specified folder
    console.log("Listing files from dependency packages");
    var numDeps = dependencies.length;
    var filesToCopy = {};
    var repoQuery;
    var errorMsg;
    // We make a consolidated set containing all the files
    // that need to be copied
    async.forEachOf(dependencies, function (value, dep, forEachCallback) {
    if ( dependencies.hasOwnProperty(dep) ) {
    try {
    repoQuery = child_process.spawn('repoquery', ['-l', dep]);
    repoQuery.stdout.on('data', function (data) {
    data.toString().split('\n').forEach( function(line) {
    //if(line.trim().length > 0){
    filesToCopy[line] = true;
    //}
    });
    });
    repoQuery.on('close', function (errCode) {
    forEachCallback();
    });
    repoQuery.stderr.on('data', function (error) {
    });
    } catch (e) {
    forEachCallback("Unable to call repoquery: " + e);
    }
    }
    }, function (err) {
    if (err) {
    callback(err, null);
    } else {
    callback(null, commandlineArgs, filesToCopy);
    }
    });
    },
    function (commandlineArgs, filesToCopy, callback) {
    // Here we actually make the copies of all files
    console.log('Copying dependency files into destination folder');
    var re = /\/usr\/(.*)/;
    var symbolicLinksNeeded = [];
    var destDir = commandlineArgs[3];
    async.forEachOf(filesToCopy, function (value, file, forEachCallback) {
    var pathMatches;
    pathMatches = file.match(re);
    if(!pathMatches){
    if(file.trim().length !== 0){
    console.error('Error: Dont know how to copy: ' + file + '. Skipping.');
    }
    forEachCallback(null);
    } else {
    var destPath = path.join(destDir, pathMatches[1]);
    console.log("Attempting file: " + file);
    fs.lstat(file, function (err, stat) {
    if (err) {
    console.error("Error: No such file: " + file + ". Skipping...");
    forEachCallback(null);
    } else if(stat.isDirectory()) {
    forEachCallback(null);
    } else if(stat.isFile() /*|| stat.isSymbolicLink()*/) {
    console.log('Copying: ' + file + ' to ' + destPath);
    fs.copy(file, destPath, function (err) {
    if(err){
    console.error('Error: Unable to copy file: ' + file);
    }
    forEachCallback(null);
    });
    } else {
    console.error('Error: Unhandled file type: ' + file);
    forEachCallback(null);
    }
    });
    }
    }, function (err) {
    if (err) {
    callback(err, null);
    } else {
    callback(null, "Done");
    }
    });
    }
    ], function (err, result) {
    if(err){
    console.error(err);
    process.exit(1);
    }else if(result){
    console.log(result);
    process.exit(0);
    }
    });