Example #1
0
  _expand_template(options) {
    var data = {
      _keep_key(key) {
        return "#{" + key + "}";
      },
      system: {
        name: this.name,
      },
      manifest: {
        dir : this.manifest.manifestDirName,
        path: this.manifest.manifestPath,
        project_name: this.manifest.manifestDirName,
      },
      azk: {
        version       : version,
        default_domain: config('agent:balancer:host'),
        default_dns   : net.nameServers(),
        balancer_port : config('agent:balancer:port'),
        balancer_ip   : config('agent:balancer:ip'),
      },
      env: process.env,
    };

    var template = this._replace_keep_keys(JSON.stringify(options));
    return JSON.parse(utils.template(template, data));
  }
Example #2
0
    return async(this, function* () {
      // Get agent status
      var agent = yield lazy.Client.status();
      var require_vm = config("agent:requires_vm");

      // Load configs from agent
      if (agent.agent) {
        yield Helpers.requireAgent(this.ui);
      }

      // Mount data to render
      var data = {
        version: Azk.version,
        docker: require_vm && !agent.agent ? { Version: this.ui.c.red("down") } : yield this.docker.version(),
        use_vm: require_vm ? this.ui.c.green("yes") : this.ui.c.yellow("no"),
        agent_running: agent.agent ? this.ui.c.green("up") : this.ui.c.red("down"),
      };

      if (require_vm && agent.agent) {
        var ip = config('agent:vm:ip');
        data.use_vm = data.use_vm + ', ip: ' + this.ui.c.yellow(ip);
      }

      var render = opts.logo ? this.render_with_logo : this.render_normal;
      this.ui.output(render.apply(this, [data]));
      return 0;
    });
Example #3
0
    return Tools.async_status("balancer", this, function* (change_status) {
      if (!this.isRunnig()) {
        var socket = config('paths:memcached_socket');
        var ip     = net.calculateGatewayIp(config("agent:vm:ip"))
        var port   = yield net.getPort();

        // Memcached
        change_status("starting_memcached");
        yield this.start_memcached(socket);
        change_status("started_memcached");

        // Hipache
        change_status("starting_hipache");
        yield this.start_hipache(ip, port, socket);
        change_status("started_hipache");

        // Dns server
        change_status("starting_dns");
        yield this.start_dns(ip, port);
        change_status("started_dns");

        // Socat
        change_status("starting_socat");
        yield this.start_socat(ip, port);
        change_status("started_socat");
      }
    });
Example #4
0
    return async(function* () {
      // Copy structure
      var tmp = yield h.copyToTmp(h.fixture_path('test-app'));
      var default_img = config('docker:image_default');

      var command   = "socat TCP4-LISTEN:$PORT EXEC:`pwd`/src/bashttpd";
      var provision = ["ls -l ./src", "./src/bashttpd", "exit 0"];

      // Data merge
      data = _.merge({
        systems: {
          example: {
            depends: ["db", "api"],
            workdir: '/azk/<%= manifest.dir %>',
            image: default_img,
            mount_folders: true,
            balancer: true,
            command, provision,
            envs: {
              ECHO_DATA: "data"
            }
          },
          api: {
            depends: ["db"],
            workdir: '/azk/<%= manifest.dir %>',
            image: default_img,
            mount_folders: true,
            balancer: true,
            command, provision,
            envs: {
              ECHO_DATA: "data"
            }
          },
          db: {
            workdir: '/azk/<%= manifest.dir %>',
            image: default_img,
            persistent_folders: [ "/data" ],
            mount_folders: false,
            balancer: false,
            command, provision,
          },
          empty: {
            image: config('docker:image_empty'),
            command: "/bin/false"
          },
        },
        default: 'example',
        bins: [
          { name: "console", command: ["bundler", "exec"] }
        ]
      }, data);

      // Read and write
      var generator = new Generator({});
      generator.render(data, path.join(tmp, config('manifest')));

      // Return a new project dir
      return tmp;
    });
Example #5
0
    it('should default', function () {
      var name_servers_options = { resolv_path: false };
      var default_nameservers       = config('agent:dns:defaultserver');
      var full_default_nameservers  = [ config("agent:dns:ip") ].concat(default_nameservers);

      h.expect(full_default_nameservers).to.eql(net_utils.nameServers(name_servers_options));
      h.expect(full_default_nameservers).to.eql(config(cache_key));
    });
Example #6
0
  // TODO: Add test
  static resolvePath(target, point = config('agent:vm:mount_point')) {
    target = Utils.resolve(target);
    if (config('agent:requires_vm')) {
      target = path.join(point, target);
    }

    return target;
  }
Example #7
0
File: run.js Project: ReeSilva/azk
    return async(this, function* () {
      var host;
      if (config('agent:requires_vm')) {
        host = config('agent:vm:ip');
      } else {
        host = port_data.gateway;
      }

      // Wait for available
      var wait_opts = {
        timeout: timeout,
        context: `${system.name}_connect`,
        retry_if: () => {
          return container.inspect().then((data) => {
            return data.State.Running;
          });
        },
      };

      var address = `tcp://${host}:${port_data.port}`;
      publish("system.run._wait_available.status", _.merge(port_data, {
        uri :  address,
        timeout: timeout,
        name: system.portName(port_data.name),
        type: "wait_port", system: system.name
      }));

      var running = yield net.waitService(address, wait_opts);

      if (!running) {
        var data = yield container.inspect();
        var exitCode = data.State.ExitCode;

        var log = t('errors.run_timeout_error', {
          system: system.name,
          port: port_data && port_data.port,
          timeout: timeout,
          hostname: lazy.colors.underline(system.url),
        });

        // Format command
        var command = system.printableCommand(data, image_conf);

        if (exitCode === 0) {
          throw new SystemRunError(
            system.name,
            container,
            command,
            exitCode,
            log
          );
        } else {
          yield this.throwRunError(system, container, command, null, true, options);
        }
      }

      return true;
    });
Example #8
0
File: vm.js Project: leohmoraes/azk
        .then(() => {
          var ssh_url  = `${config('agent:vm:user')}@${config('agent:vm:ip')}`;
          var ssh_opts = "StrictHostKeyChecking=no -o LogLevel=quiet -o UserKnownHostsFile=/dev/null";
          var args     = (params['ssh-args'] || []).join(`" "`);
          var script   = `ssh -i ${config('agent:vm:ssh_key')} -o ${ssh_opts} ${ssh_url} "${args}"`;

          log.debug(script);
          return this.ui.execSh(script);
        });
Example #9
0
        return generate_manifest(dir, data).then(function(manifest) {
          var system     = manifest.systemDefault;
          var re_default = RegExp(h.escapeRegExp(`${system.name}.${config('agent:balancer:host')}`));
          var re_custom  = RegExp(h.escapeRegExp(`custom.${config('agent:balancer:host')}`));

          h.expect(system).to.have.deep.property('hosts').and.length(2);
          h.expect(system).to.have.deep.property('hosts[0]').and.match(re_default);
          h.expect(system).to.have.deep.property('hosts[1]').and.match(re_custom);
        });
Example #10
0
 return image.inspect().then((image_data) => {
   var options = system.daemonOptions({ image_data });
   h.expect(options).to.have.property("working_dir", "/data");
   h.expect(options).to.have.property("command").and.eql(image_data.Config.Cmd);
   h.expect(options).to.have.deep.property("ports.80/tcp").and.eql([{
     HostIp: config('agent:dns:ip')
   }]);
   h.expect(options).to.have.deep.property("ports.53/udp").and.eql([{
     HostIp: config('agent:dns:ip')
   }]);
 });
Example #11
0
 it("should expand options with template", function() {
   var system    = manifest.system('expand-test');
   var provision = system.options.provision;
   h.expect(provision).to.include(`system.name: ${system.name}`);
   h.expect(provision).to.include(`system.persistent_folders: /data`);
   h.expect(provision).to.include(`manifest.dir: ${manifest.manifestDirName}`);
   h.expect(provision).to.include(`manifest.path: ${manifest.manifestPath}`);
   h.expect(provision).to.include(`manifest.project_name: ${manifest.manifestDirName}`);
   h.expect(provision).to.include(`azk.default_domain: ${config('agent:balancer:host')}`);
   h.expect(provision).to.include(`azk.balancer_port: ${config('agent:balancer:port').toString()}`);
   h.expect(provision).to.include(`azk.balancer_ip: ${config('agent:balancer:ip')}`);
 });
Example #12
0
    return async(this, function* (notify) {
      var host;
      if (config('agent:requires_vm')) {
        host = config('agent:vm:ip');
      } else {
        host = port_data.gateway;
      }

      // Wait for available
      var wait_opts = {
        timeout: timeout,
        context: `${system.name}_connect`,
        retry_if: () => {
          return container.inspect().then((data) => {
            return data.State.Running;
          });
        },
      };

      notify(_.merge(port_data, {
        name: system.portName(port_data.name),
        type: "wait_port", system: system.name
      }));

      var address = `tcp://${host}:${port_data.port}`;
      var running = yield net.waitService(address, retry, wait_opts);

      if (!running) {
        var data = yield container.inspect();
        var exitCode = data.State.ExitCode;

        if (exitCode === 0) {
          throw new SystemRunError(
            system.name,
            container,
            data.Config.Cmd.join(' '),
            exitCode,
            Q(t('errors.run_timeout_error', {
              system: system.name,
              port: port_data && port_data.port,
              retry: retry,
              timeout: timeout,
              hostname: system.url.underline,
            }))
          );
        } else {
          yield this.throwRunError(system, container, null, true);
        }
      }

      return true;
    });
Example #13
0
File: dustman.js Project: awlka/azk
export function extend(Helpers) {
  var t_regexs = [
    RegExp(`${Helpers.escapeRegExp(config('docker:image_empty'))}`),
    RegExp(`${Helpers.escapeRegExp(config('docker:repository'))}`),
  ]
  var filter_tags = (tag) => {
    return _.some(t_regexs, (regex) => { return tag.match(regex) });
  }

  Helpers.remove_containers = function() {
    return defer((done) => {
      return docker.azkListContainers({ all: true }).then((containers) => {
        done.notify(t('test.remove_containers', containers.length));
        return Q.all(_.map(containers, (container) => {
          var c = docker.getContainer(container.Id);
          return c.kill().then(() => {
            return c.remove({ force: true });
          });
        }));
      });
    });
  }

  Helpers.remove_images = function() {
    return defer((done) => {
      return docker.listImages().then((images) => {
        var tags = _.flatten(_.map(
          images, (image) => { return image.RepoTags }
        ));

        tags = _.filter(tags, filter_tags);
        done.notify(t('test.remove_images', tags.length));

        return Q.all(_.map(tags, (tag) => {
          return docker.getImage(tag).remove();
        }));
      });
    });
  }

  // Remove all containers before run
  before(function() {
    this.timeout(0);
    var progress = (event) => console.log(`  ${event}`);
    var funcs = [
      Helpers.remove_containers,
      Helpers.remove_images,
      () => console.log("\n")
    ]
    return funcs.reduce(Q.when, Q()).progress(progress);
  });
}
Example #14
0
 it("should expand options with template", function() {
   var system = manifest.system('expand-test');
   var mount_folders = system.raw_mount_folders;
   h.expect(mount_folders).to.eql({
     "system_name": system.name,
     "persistent_folder": "/data",
     "manifest_dir": manifest.manifestDirName,
     "manifest_project_name": manifest.manifestDirName,
     "azk_default_domain": config('agent:balancer:host'),
     "azk_balancer_port": config('agent:balancer:port').toString(),
     "azk_balancer_ip": config('agent:balancer:ip'),
   })
 });
Example #15
0
          return image.inspect().then((image_data) => {
            var options = system.daemonOptions({ image_data });

            h.expect(options).to.deep.have.property("ports.5000/tcp").and.eql([{
              HostIp: config('agent:dns:ip')
            }]);
            h.expect(options).to.deep.have.property("ports.80/tcp").and.eql([{
              HostIp: config('agent:dns:ip')
            }]);
            h.expect(options).to.deep.have.property("ports.53/tcp").and.eql([{
              HostIp: config('agent:dns:ip')
            }]);
          });
Example #16
0
      it("should map system ports to docker ports", function() {
        var system  = manifest.system('ports-test');
        var options = system.daemonOptions();

        h.expect(options).to.deep.have.property("ports.80/tcp").and.eql([{
          HostIp: config('agent:dns:ip')
        }]);
        h.expect(options).to.deep.have.property("ports.53/udp").and.eql([{
          HostIp: config('agent:dns:ip')
        }]);
        h.expect(options).to.deep.have.property("ports.443/tcp").and.eql([{
          HostIp: config('agent:dns:ip'), HostPort: "443"
        }]);
      });
Example #17
0
File: init.js Project: awlka/azk
    return async(this, function* () {
      var manifest = config("manifest");
      var cwd  = opts.path || this.cwd;
      var file = path.join(cwd, manifest);
      var generator = new Generator(this);

      if (fs.existsSync(file) && !opts.force) {
        this.fail(this.tKeyPath("already"), manifest);
        return 1;
      }

      var systems = generator.findSystems(cwd);
      if (_.isEmpty(systems)) {
        this.fail(this.tKeyPath("not_found"));
        systems = { [example_system.name]: example_system };
      }

      generator.render({ systems }, file);
      this.ok(this.tKeyPath('generated'), manifest);

      // Only show tips if is a git dir
      if (fs.existsSync(path.join(cwd, ".git")))
        this.tOutput(this.tKeyPath('github'));

      return 0;
    });
Example #18
0
  action(opts) {
    if (opts.filename) {
      return this.showFilename();
    }

    var manifest = config("manifest");
    var cwd  = opts.path || this.cwd;
    var file = path.join(cwd, manifest);
    var generator = new lazy.Generator(this);

    if (fs.existsSync(file) && !opts.force) {
      this.fail(this.tKeyPath("already_exists"), manifest);
      return 1;
    }

    var systemsData = generator.findSystems(cwd);
    log.debug('generator.findSystems(\'%s\')', cwd);

    if (_.isEmpty(systemsData)) {
      this.fail(this.tKeyPath("not_found"));
      systemsData = { [lazy.example_system.name]: lazy.example_system };
    }

    generator.render({ systems: systemsData }, file);
    this.ok(this.tKeyPath('generated'), manifest);

    // Only show tips if is a git dir
    if (fs.existsSync(path.join(cwd, ".git"))) {
      this.tOutput(this.tKeyPath('github'));
    }

    return 0;
  }
Example #19
0
    return _.reduce(ports, (ports, port, name) => {
      // skip disable
      if (isBlank(port)) {
        return ports;
      }

      port = XRegExp.exec(port, regex_port);
      port.protocol = port.protocol || "tcp";

      // TODO: Add support a bind ip
      var conf = { HostIp: config("agent:dns:ip") };
      if (_.isEmpty(port.private)) {
        port.private = port.public;
        port.public  = null;
      }

      if (!_.isEmpty(port.public)) {
        conf.HostPort = port.public;
      }

      ports[name] = {
        config : conf,
        key    : name,
        name   : port.private + "/" + port.protocol,
        private: port.private
      };
      return ports;
    }, {});
Example #20
0
  _mounts_to_volumes(mounts) {
    var volumes = {};

    // persistent folder
    var persist_base = config('paths:persistent_folders');
    persist_base = path.join(persist_base, this.manifest.namespace);

    return _.reduce(mounts, (volumes, mount, point) => {
      if (_.isString(mount)) {
        mount = { type: 'path', value: mount }
      }

      var target = null;
      switch(mount.type) {
        case 'path':
          target = mount.value;
          if (!target.match(/^\//)) {
            target = path.resolve(this.manifest.manifestPath, target);
          }
          target = (fs.existsSync(target)) ?
            utils.docker.resolvePath(target) : null;
          break;
        case 'persistent':
          target = path.join(persist_base, mount.value);
          break;
      }

      if (!_.isEmpty(target)) {
        volumes[point] = target;
      }

      return volumes;
    }, volumes);
  }
Example #21
0
 it("should bind port", function() {
   h.expect(instances).to.have.deep.property('[0].Ports[0]');
   var port = instances[0].Ports[0];
   h.expect(port).to.have.property('IP', config('agent:vm:ip'));
   h.expect(port).to.have.property('PublicPort');
   h.expect(port).to.have.property('Type', 'tcp');
 });
Example #22
0
 get cache_dir() {
   return path.join(
     this.cwd,
     config('azk_dir'),
     this.file_relative
   )
 }
Example #23
0
 var generateAndReturnManifest = (project) => {
   var manifest = path.join(project, config('manifest'));
   generator.render({
     systems: generator.findSystems(project),
   }, manifest);
   return new Manifest(project);
 }
Example #24
0
      it('should generate a multiple hosts', function() {
        var data = _.clone(default_data);
        data.systems.front.http = [
          '#{system.name}.#{azk.default_domain}',
          'custom.#{azk.default_domain}',
        ];

        var manifest   = generate_manifest(dir, data);
        var system     = manifest.systemDefault;
        var re_default = RegExp(h.escapeRegExp(`${system.name}.${config('agent:balancer:host')}`));
        var re_custom  = RegExp(h.escapeRegExp(`custom.${config('agent:balancer:host')}`));

        h.expect(system).to.have.deep.property('hosts').and.length(2);
        h.expect(system).to.have.deep.property('hosts[0]').and.match(re_default);
        h.expect(system).to.have.deep.property('hosts[1]').and.match(re_custom);
      });
Example #25
0
File: api.js Project: lucasfais/azk
 app.get('/configs', (req, res) => {
   var keys = config('agent:config_keys');
   res.json(_.reduce(keys, (acc, key) => {
     acc[key] = config(key);
     return acc;
   }, {}));
 });
Example #26
0
File: vm.js Project: leohmoraes/azk
    return async(this, function* () {
      var action  = _.head((this.route && this.route.actions)) || options.action;
      var vm_name = config("agent:vm:name");
      var vm_info = yield lazy.VM.info(vm_name);

      var promise = this[`action_${action}`](vm_info, options);

      var _subscription = subscribe('vm.action.status', (data) => {
        Helpers.vmStartProgress(this.ui)(data);
      });

      return promise
        .then(function (result) {
          _subscription.unsubscribe();
          return result;
        })
        .catch(options.fail || ((error) => {
          if (error instanceof RequiredError) {
            this.ui.fail(error.key);
            return 1;
          }
          _subscription.unsubscribe();
          throw error;
        }));
    });
Example #27
0
      it("should support custom options", function() {
        // Customized options
        var custom  = {
          mounts : {
            "/azk"  : { type: 'path', value: '.' },
            "/data" : { type: 'persistent', value: 'data' },
          },
          workdir : "/azk",
          envs    : { FOO: "BAR" },
          sequencies: { daemon: 2 }
        };
        var options = system.daemonOptions(custom);
        var mounts  = options.volumes;
        var folder  = path.join(
          config("paths:persistent_folders"),
          manifest.namespace, "data"
        );

        h.expect(options).to.have.property("working_dir", "/azk");
        h.expect(options).to.have.property("volumes")
        h.expect(options).to.have.deep.property("annotations.azk.seq", 2);
        h.expect(options).to.have.property("env").and.eql({
          ECHO_DATA    : "data",
          FROM_DOT_ENV : "azk is beautiful",
          HTTP_PORT    : "5000",
          FOO          : "BAR"
        });

        h.expect(mounts).to.have.property(
          "/azk", utils.docker.resolvePath(manifest.manifestPath)
        );
        h.expect(mounts).to.have.property("/data", folder);
      });
Example #28
0
  constructor(cwd, file = null, required = false) {
    if (typeof file == "boolean") {
      [required, file] = [file, null];
    }

    if (required && !cwd) {
      throw new Error(t("manifest.required_path"));
    }

    this.images   = {};
    this.systems  = {};
    this.bins     = {};
    this._default = null;
    this.file     = file || Manifest.find_manifest(cwd);

    if (required && !this._exist()) {
      throw new ManifestRequiredError(cwd);
    }

    // Create cache for application status
    if (_.isEmpty(this.cache_dir) && this._exist()) {
      this.cache_dir = path.join(this.cwd, config('azk_dir'), this._file_relative());
    }
    this.meta = new Meta(this);

    if (this._exist()) {
      this.parse();
    }
  }
Example #29
0
File: run.js Project: ReeSilva/azk
      return async(this, function* () {
        if (daemon && sync_data.options.daemon === false ||
           !daemon && sync_data.options.shell !== true) {
          return promiseResolve();
        }

        if (config('agent:requires_vm')) {
          sync_data.options = _.defaults(sync_data.options, { use_vm: true, ssh: lazy.Client.ssh_opts() });
        }

        var clean_sync_folder = yield this._clean_sync_folder(system, host_folder);
        if (clean_sync_folder !== 0) {
          // TODO: throw proper error
          throw new NotBeenImplementedError('SyncError');
        }

        var pub_data = {
          system      : system.name,
          host_folder : host_folder,
          guest_folder: sync_data.guest_folder,
          options     : sync_data.options
        };

        publish(topic, _.assign({ type : "sync_start" }, pub_data));

        return lazy.Client
          .watch(host_folder, sync_data.guest_folder, sync_data.options)
          .then(() => {
            publish(topic, _.assign({ type : "sync_done" }, pub_data));
          });
      });
Example #30
0
    return defer((done) => {
      var child_process = require('child_process');

      log.debug("Launching agent in daemon mode");
      var child = child_process.fork(__filename, [], {
        silent  : true,
        detached: true,
        cwd     : config('paths:azk_root'),
        env     : _.extend({
        }, process.env),
      }, (err, stdout, stderr) => {
        if (err) done.reject(err.stack);
      });

      var exit = () => {
        done.resolve(1);
      }

      var msg_cb = (msg) => {
        log.debug('agent child msg: %s', msg);
        this.change_status(msg.status, msg.data);
        if (msg.status == "started") {
          child.removeListener('exit', exit);
          child.removeListener('message', msg_cb);
          child.unref();
          return done.resolve(0);
        }
      };

      child.on('exit', exit);
      child.on('message', msg_cb);
    });