diff --git a/Makefile b/Makefile index 659133d4cd52..91782c660698 100644 --- a/Makefile +++ b/Makefile @@ -22,15 +22,15 @@ dev: echo "$$rock already installed, skipping" ; \ fi \ done; - bin/kong config -e TEST - bin/kong config -e DEVELOPMENT - bin/kong db -c $(DEVELOPMENT_CONF) migrations:up + bin/kong config -c kong.yml -e TEST + bin/kong config -c kong.yml -e DEVELOPMENT + bin/kong migrations -c $(DEVELOPMENT_CONF) up clean: @rm -f luacov.* @rm -f $(DEVELOPMENT_CONF) $(TESTING_CONF) @rm -rf nginx_tmp - @bin/kong db -c $(DEVELOPMENT_CONF) migrations:reset + @bin/kong migrations -c $(DEVELOPMENT_CONF) reset run: @bin/kong start -c $(DEVELOPMENT_CONF) diff --git a/bin/kong b/bin/kong index 01f39176dba6..6df33cede40e 100755 --- a/bin/kong +++ b/bin/kong @@ -1,7 +1,17 @@ #!/usr/bin/env lua +-- Kong CLI entry-point (bin/kong). +-- +-- Kong's CLI is a set of small commands invoked by a global executable, this file. +-- +-- All commands are invoked by this script, then parsed (arguments and options) +-- by lapp (see http://lua-users.org/wiki/LappFramework). +-- +-- This script is not parsed by lapp due to limitations of the said framework as it +-- is currently implemented. + local cutils = require "kong.cli.utils" -local infos = cutils.get_infos() +local infos = cutils.get_kong_infos() local commands = { db = "kong.cli.db", stop = "kong.cli.stop", @@ -9,24 +19,25 @@ local commands = { start = "kong.cli.start", reload = "kong.cli.reload", config = "kong.cli.config", + restart = "kong.cli.restart", version = "kong.cli.version", ["--version"] = "kong.cli.version", - restart = "kong.cli.restart" + migrations = "kong.cli.migrations" } local help_message = string.format([[ Usage: kong -where is one of: - start, stop, quit, restart, reload, config, db, version + where is one of: + start, restart, reload, stop, quit, version -kong --help print this message -kong --help print the help message of a command + kong --help print this message + kong --help print the help message of a command %s@%s]], infos.name, infos.version) +-- Determine validity of the given command local cmd = arg[1] - if not cmd then print("Missing \n\n"..help_message) os.exit(1) @@ -38,4 +49,5 @@ elseif not commands[cmd] then os.exit(1) end +-- Load and execute desired command require(commands[cmd]) diff --git a/kong-0.2.0-1.rockspec b/kong-0.2.0-1.rockspec index bb142d26a8c8..ef85885be48d 100644 --- a/kong-0.2.0-1.rockspec +++ b/kong-0.2.0-1.rockspec @@ -48,6 +48,7 @@ build = { ["kong.cli.reload"] = "src/cli/reload.lua", ["kong.cli.restart"] = "src/cli/restart.lua", ["kong.cli.version"] = "src/cli/version.lua", + ["kong.cli.migrations"] = "src/cli/migrations.lua", ["kong.tools.utils"] = "src/tools/utils.lua", ["kong.tools.io"] = "src/tools/io.lua", diff --git a/src/cli/config.lua b/src/cli/config.lua index f69b94d65b94..1a1b1b8961b6 100644 --- a/src/cli/config.lua +++ b/src/cli/config.lua @@ -4,12 +4,14 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local IO = require "kong.tools.io" local args = require("lapp")(string.format([[ +For development purposes only. + Duplicate an existing configuration for given environment. Usage: kong config [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file -o,--output (default .) ouput -e,--env (string) environment name ]], constants.CLI.GLOBAL_KONG_CONF)) diff --git a/src/cli/db.lua b/src/cli/db.lua index 29d7491fe1dd..b6350d6de315 100644 --- a/src/cli/db.lua +++ b/src/cli/db.lua @@ -1,25 +1,25 @@ #!/usr/bin/env lua local Faker = require "kong.tools.faker" -local Migrations = require "kong.tools.migrations" - local constants = require "kong.constants" local cutils = require "kong.cli.utils" local IO = require "kong.tools.io" local lapp = require("lapp") local args = lapp(string.format([[ -Migrations, seeding of the DB. +For development purposes only. + +Seed the database with random data or drop it. Usage: kong db [options] Commands: (string) where is one of: - migrations, migrations:up, migrations:down, migrations:reset, seed, drop + seed, drop Options: - -c,--config (default %s) configuration file - -r,--random : flag to also insert random entities - -n,--number (default 1000) : number of random entities to insert if --random + -c,--config (default %s) path to configuration file + -r,--random flag to also insert random entities + -n,--number (default 1000) number of random entities to insert if --random ]], constants.CLI.GLOBAL_KONG_CONF)) -- $ kong db @@ -29,83 +29,8 @@ end local config_path = cutils.get_kong_config_path(args.config) local _, dao_factory = IO.load_configuration_and_dao(config_path) -local migrations = Migrations(dao_factory, cutils.get_luarocks_install_dir()) - -if args.command == "migrations" then - - local migrations, err = dao_factory:get_migrations() - if err then - cutils.logger:error_exit(err) - elseif migrations then - cutils.logger:log(string.format( - "Executed migrations for %s on keyspace: %s:\n%s", - cutils.colors.yellow(dao_factory.type), - cutils.colors.yellow(dao_factory._properties.keyspace), - table.concat(migrations, ", ") - )) - else - cutils.logger:log(string.format( - "No migrations have been run yet for %s on keyspace: %s", - cutils.colors.yellow(dao_factory.type), - cutils.colors.yellow(dao_factory._properties.keyspace) - )) - end - -elseif args.command == "migrations:up" then - - cutils.logger:log(string.format( - "Migrating %s keyspace: %s", - cutils.colors.yellow(dao_factory.type), - cutils.colors.yellow(dao_factory._properties.keyspace)) - ) - - migrations:migrate(function(migration, err) - if err then - cutils.logger:error_exit(err) - elseif migration then - cutils.logger:success("Migrated up to: "..cutils.colors.yellow(migration.name)) - else - cutils.logger:success("Schema already up to date") - end - end) - -elseif args.command == "migrations:down" then - - cutils.logger:log(string.format( - "Rolling back %s keyspace: %s", - cutils.colors.yellow(dao_factory.type), - cutils.colors.yellow(dao_factory._properties.keyspace) - )) - - migrations:rollback(function(migration, err) - if err then - cutils.logger:error_exit(err) - elseif migration then - cutils.logger:success("Rollbacked to: "..cutils.colors.yellow(migration.name)) - else - cutils.logger:success("No migration to rollback") - end - end) - -elseif args.command == "migrations:reset" then - - cutils.logger:log(string.format( - "Reseting %s keyspace: %s", - cutils.colors.yellow(dao_factory.type), - cutils.colors.yellow(dao_factory._properties.keyspace)) - ) - - migrations:reset(function(migration, err) - if err then - cutils.logger:error_exit(err) - elseif migration then - cutils.logger:success("Rollbacked: "..cutils.colors.yellow(migration.name)) - else - cutils.logger:success("Schema reseted") - end - end) -elseif args.command == "seed" then +if args.command == "seed" then -- Drop if exists local err = dao_factory:drop() diff --git a/src/cli/migrations.lua b/src/cli/migrations.lua new file mode 100644 index 000000000000..15d63c7b0684 --- /dev/null +++ b/src/cli/migrations.lua @@ -0,0 +1,106 @@ +#!/usr/bin/env lua + +local Migrations = require "kong.tools.migrations" +local constants = require "kong.constants" +local cutils = require "kong.cli.utils" +local IO = require "kong.tools.io" +local lapp = require("lapp") +local args = lapp(string.format([[ +Kong datastore migrations. + +Usage: kong migrations [options] + +Commands: + (string) where is one of: + list, up, down, reset + +Options: + -c,--config (default %s) path to configuration file +]], constants.CLI.GLOBAL_KONG_CONF)) + +-- $ kong migrations +if args.command == "migrations" then + lapp.quit("Missing required .") +end + +local config_path = cutils.get_kong_config_path(args.config) +local _, dao_factory = IO.load_configuration_and_dao(config_path) +local migrations = Migrations(dao_factory, cutils.get_luarocks_install_dir()) + +if args.command == "list" then + + local migrations, err = dao_factory:get_migrations() + if err then + cutils.logger:error_exit(err) + elseif migrations then + cutils.logger:log(string.format( + "Executed migrations for %s on keyspace %s:\n%s", + cutils.colors.yellow(dao_factory.type), + cutils.colors.yellow(dao_factory._properties.keyspace), + table.concat(migrations, ", ") + )) + else + cutils.logger:log(string.format( + "No migrations have been run yet for %s on keyspace: %s", + cutils.colors.yellow(dao_factory.type), + cutils.colors.yellow(dao_factory._properties.keyspace) + )) + end + +elseif args.command == "up" then + + cutils.logger:log(string.format( + "Migrating %s keyspace: %s", + cutils.colors.yellow(dao_factory.type), + cutils.colors.yellow(dao_factory._properties.keyspace)) + ) + + migrations:migrate(function(migration, err) + if err then + cutils.logger:error_exit(err) + elseif migration then + cutils.logger:success("Migrated up to: "..cutils.colors.yellow(migration.name)) + else + cutils.logger:success("Schema already up to date") + end + end) + +elseif args.command == "down" then + + cutils.logger:log(string.format( + "Rolling back %s keyspace: %s", + cutils.colors.yellow(dao_factory.type), + cutils.colors.yellow(dao_factory._properties.keyspace) + )) + + migrations:rollback(function(migration, err) + if err then + cutils.logger:error_exit(err) + elseif migration then + cutils.logger:success("Rollbacked to: "..cutils.colors.yellow(migration.name)) + else + cutils.logger:success("No migration to rollback") + end + end) + +elseif args.command == "reset" then + + cutils.logger:log(string.format( + "Reseting %s keyspace: %s", + cutils.colors.yellow(dao_factory.type), + cutils.colors.yellow(dao_factory._properties.keyspace)) + ) + + migrations:reset(function(migration, err) + if err then + cutils.logger:error_exit(err) + elseif migration then + cutils.logger:success("Rollbacked: "..cutils.colors.yellow(migration.name)) + else + cutils.logger:success("Schema reseted") + end + end) + +else + lapp.quit("Invalid command: "..args.command) +end diff --git a/src/cli/quit.lua b/src/cli/quit.lua index 091e791e169f..ee620409e387 100644 --- a/src/cli/quit.lua +++ b/src/cli/quit.lua @@ -4,12 +4,12 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local signal = require "kong.cli.utils.signal" local args = require("lapp")(string.format([[ -Graceful shutdown +Graceful shutdown. Stop the Kong instance running in the configured 'nginx_working_dir' directory. Usage: kong stop [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) -- Check if running, will exit if not diff --git a/src/cli/reload.lua b/src/cli/reload.lua index 40e8062621b7..fdffccd0a1d9 100644 --- a/src/cli/reload.lua +++ b/src/cli/reload.lua @@ -4,12 +4,14 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local signal = require "kong.cli.utils.signal" local args = require("lapp")(string.format([[ -Gracefully reload Kong applying any configuration changes (including nginx) +Gracefully reload the Kong instance running in the configured 'nginx_working_dir'. + +Any configuration change will be applied. Usage: kong reload [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) signal.prepare_kong(args.config) diff --git a/src/cli/restart.lua b/src/cli/restart.lua index 0a2e12a06d02..578668018f73 100644 --- a/src/cli/restart.lua +++ b/src/cli/restart.lua @@ -4,10 +4,15 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local signal = require "kong.cli.utils.signal" local args = require("lapp")(string.format([[ +Restart the Kong instance running in the configured 'nginx_working_dir'. + +Kong will be shutdown before restarting. For a zero-downtime reload +of your configuration, look at 'kong reload'. + Usage: kong restart [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) if signal.is_running(args.config) then diff --git a/src/cli/start.lua b/src/cli/start.lua index e90b809d140f..1f5813a527e5 100755 --- a/src/cli/start.lua +++ b/src/cli/start.lua @@ -4,10 +4,12 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local signal = require "kong.cli.utils.signal" local args = require("lapp")(string.format([[ +Start Kong with given configuration. Kong will run in the configured 'nginx_working_dir' directory. + Usage: kong start [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) signal.prepare_kong(args.config) diff --git a/src/cli/stop.lua b/src/cli/stop.lua index 9ffaf68955b1..552b184df7cb 100755 --- a/src/cli/stop.lua +++ b/src/cli/stop.lua @@ -4,12 +4,12 @@ local constants = require "kong.constants" local cutils = require "kong.cli.utils" local signal = require "kong.cli.utils.signal" local args = require("lapp")(string.format([[ -Fast shutdown +Fast shutdown. Stop the Kong instance running in the configured 'nginx_working_dir' directory. Usage: kong stop [options] Options: - -c,--config (default %s) configuration file + -c,--config (default %s) path to configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) -- Check if running, will exit if not diff --git a/src/cli/utils/signal.lua b/src/cli/utils/signal.lua index 5c57a10dcbf2..c9a5ff4477da 100644 --- a/src/cli/utils/signal.lua +++ b/src/cli/utils/signal.lua @@ -41,21 +41,21 @@ local function is_openresty(path_to_check) return out:match("^nginx version: ngx_openresty/") or out:match("^nginx version: openresty/") end --- Find an `nginx` executable in defined paths +-- Paths where to search for an `nginx` executable in addition to the usual $PATH +local NGINX_BIN = "nginx" +local NGINX_SEARCH_PATHS = { + "/usr/local/openresty/nginx/sbin/", + "/usr/local/opt/openresty/bin/", + "/usr/local/bin/", + "/usr/sbin/" +} + +-- Try to find an `nginx` executable in defined paths, or in $PATH -- @return Path to found executable or nil if none was found local function find_nginx() - local nginx_bin = "nginx" - local nginx_search_paths = { - "/usr/local/openresty/nginx/sbin/", - "/usr/local/opt/openresty/bin/", - "/usr/local/bin/", - "/usr/sbin/", - "" - } - - for i = 1, #nginx_search_paths do - local prefix = nginx_search_paths[i] - local to_check = prefix..nginx_bin + for i = 1, #NGINX_SEARCH_PATHS + 1 do + local prefix = NGINX_SEARCH_PATHS[i] and NGINX_SEARCH_PATHS[i] or "" + local to_check = prefix..NGINX_BIN if is_openresty(to_check) then return to_check end @@ -133,7 +133,7 @@ function _M.send_signal(args_config, signal) -- Make sure nginx is there and is openresty local nginx_path = find_nginx() if not nginx_path then - cutils.logger:error_exit("can't find nginx") + cutils.logger:error_exit(string.format("Kong cannot find an 'nginx' executable.\nMake sure it is in your $PATH or in one of the following directories:\n%s", table.concat(NGINX_SEARCH_PATHS, "\n"))) end local kong_config_path, kong_config = get_kong_config_path(args_config) diff --git a/src/cli/utils/utils.lua b/src/cli/utils/utils.lua index 6e05636772d9..f82918048022 100644 --- a/src/cli/utils/utils.lua +++ b/src/cli/utils/utils.lua @@ -34,19 +34,23 @@ function Logger:log(str) end function Logger:success(str) - self:log(colors.green("[SUCCESS] ")..str) + self:log(colors.green("[OK] ")..str) end function Logger:warn(str) - self:log(colors.yellow("[WARNING] ")..str) + self:log(colors.yellow("[WARN] ")..str) end function Logger:error(str) - self:log(colors.red("[ERROR] ")..str) + self:log(colors.red("[ERR] ")..str) end function Logger:error_exit(str) + print("") self:error(str) + -- Optional stacktrace + --print("") + --error("", 2) os.exit(1) end @@ -55,14 +59,14 @@ local logger = Logger() -- -- Luarocks -- -local function get_infos() +local function get_kong_infos() return { name = constants.NAME, version = constants.VERSION } end local function get_luarocks_dir() local cfg = require "luarocks.cfg" local search = require "luarocks.search" - local infos = get_infos() + local infos = get_kong_infos() local tree_map = {} local results = {} @@ -83,13 +87,13 @@ end local function get_luarocks_config_dir() local repo = get_luarocks_dir() - local infos = get_infos() + local infos = get_kong_infos() return lpath.conf_dir(infos.name:lower(), infos.version, repo) end local function get_luarocks_install_dir() local repo = get_luarocks_dir() - local infos = get_infos() + local infos = get_kong_infos() return lpath.install_dir(infos.name:lower(), infos.version, repo) end @@ -111,7 +115,7 @@ local function get_kong_config_path(args_config) -- TODO: validate configuration --[[local status, res = pcall(require, "kong.dao."..config.database..".factory") if not status then - logger:error("Wrong config") + logger:error("Erroneous config") os.exit(1) end]] @@ -121,7 +125,7 @@ end return { colors = colors, logger = logger, - get_infos = get_infos, + get_kong_infos = get_kong_infos, get_kong_config_path = get_kong_config_path, get_luarocks_install_dir = get_luarocks_install_dir } diff --git a/src/cli/version.lua b/src/cli/version.lua index a6dec1bf98d4..2d485ac9eb63 100644 --- a/src/cli/version.lua +++ b/src/cli/version.lua @@ -1,6 +1,6 @@ #!/usr/bin/env lua local cutils = require "kong.cli.utils" -local infos = cutils.get_infos() +local infos = cutils.get_kong_infos() cutils.logger:log(string.format("Kong version: %s", infos.version)) diff --git a/src/dao/schemas.lua b/src/dao/schemas.lua index 5ac43891dbc6..13eadd917b8a 100644 --- a/src/dao/schemas.lua +++ b/src/dao/schemas.lua @@ -40,7 +40,7 @@ function _M.validate(t, schema, is_update) -- Check the given table against a given schema for column, v in pairs(schema) do - -- Set default value for the filed if given + -- Set default value for the field if given if t[column] == nil and v.default ~= nil then if type(v.default) == "function" then t[column] = v.default()