From 9a8caf962f29c45f9452bd517f439f4d522bb2ce Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Wed, 25 Mar 2015 13:32:18 -0700 Subject: [PATCH] feature: restart + refactor: better utils structure --- bin/kong | 5 +- kong-0.1.0beta-1.rockspec | 6 +- src/cli/config.lua | 7 ++- src/cli/db.lua | 3 +- src/cli/restart.lua | 14 +++++ src/cli/start.lua | 45 +-------------- src/cli/stop.lua | 18 +----- src/cli/utils/start.lua | 102 ++++++++++++++++++++++++++++++++++ src/cli/utils/stop.lua | 25 +++++++++ src/cli/{ => utils}/utils.lua | 88 +++++------------------------ src/kong.lua | 3 +- src/tools/io.lua | 85 ++++++++++++++++++++++++++++ src/tools/utils.lua | 87 +---------------------------- 13 files changed, 261 insertions(+), 227 deletions(-) create mode 100644 src/cli/restart.lua create mode 100644 src/cli/utils/start.lua create mode 100644 src/cli/utils/stop.lua rename src/cli/{ => utils}/utils.lua (52%) create mode 100644 src/tools/io.lua diff --git a/bin/kong b/bin/kong index 6deccd87092..793e9cf9f6e 100755 --- a/bin/kong +++ b/bin/kong @@ -7,14 +7,15 @@ local commands = { stop = "kong.cli.stop", start = "kong.cli.start", config = "kong.cli.config", - version = "kong.cli.version" + version = "kong.cli.version", + restart = "kong.cli.restart" } local help_message = string.format([[ Usage: kong where is one of: - start, stop, config, db, version + start, stop, restart, config, db, version kong --help print this message kong --help print the help message of a command diff --git a/kong-0.1.0beta-1.rockspec b/kong-0.1.0beta-1.rockspec index 00265334191..dcf1ad6d9cf 100644 --- a/kong-0.1.0beta-1.rockspec +++ b/kong-0.1.0beta-1.rockspec @@ -38,14 +38,18 @@ build = { ["kong.constants"] = "src/constants.lua", - ["kong.cli.utils"] = "src/cli/utils.lua", + ["kong.cli.utils"] = "src/cli/utils/utils.lua", + ["kong.cli.utils.start"] = "src/cli/utils/start.lua", + ["kong.cli.utils.stop"] = "src/cli/utils/stop.lua", ["kong.cli.db"] = "src/cli/db.lua", ["kong.cli.config"] = "src/cli/config.lua", ["kong.cli.stop"] = "src/cli/stop.lua", ["kong.cli.start"] = "src/cli/start.lua", + ["kong.cli.restart"] = "src/cli/restart.lua", ["kong.cli.version"] = "src/cli/version.lua", ["kong.tools.utils"] = "src/tools/utils.lua", + ["kong.tools.io"] = "src/tools/io.lua", ["kong.tools.migrations"] = "src/tools/migrations.lua", ["kong.tools.faker"] = "src/tools/faker.lua", ["kong.tools.cache"] = "src/tools/cache.lua", diff --git a/src/cli/config.lua b/src/cli/config.lua index d7aec424912..83d39d8fa2e 100644 --- a/src/cli/config.lua +++ b/src/cli/config.lua @@ -1,7 +1,8 @@ #!/usr/bin/env lua -local cutils = require "kong.cli.utils" local constants = require "kong.constants" +local cutils = require "kong.cli.utils" +local IO = require "kong.tools.io" local args = require("lapp")(string.format([[ Duplicate an existing configuration for given environment. @@ -16,7 +17,7 @@ Options: local CONFIG_FILENAME = string.format("kong%s.yml", args.env ~= "" and "_"..args.env or "") local config_path = cutils.get_kong_config_path(args.config) -local config_content = cutils.read_file(config_path) +local config_content = IO.read_file(config_path) local DEFAULT_ENV_VALUES = { TEST = { @@ -47,4 +48,4 @@ if DEFAULT_ENV_VALUES[args.env:upper()] then end end -cutils.write_to_file(cutils.path:join(args.output, CONFIG_FILENAME), config_content) +IO.write_to_file(IO.path:join(args.output, CONFIG_FILENAME), config_content) diff --git a/src/cli/db.lua b/src/cli/db.lua index aaa66f85b71..d95cb4d9be2 100644 --- a/src/cli/db.lua +++ b/src/cli/db.lua @@ -5,6 +5,7 @@ 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. @@ -27,7 +28,7 @@ if args.command == "db" then end local config_path = cutils.get_kong_config_path(args.config) -local _, dao_factory = cutils.load_configuration_and_dao(config_path) +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 diff --git a/src/cli/restart.lua b/src/cli/restart.lua new file mode 100644 index 00000000000..9a9a5326fcc --- /dev/null +++ b/src/cli/restart.lua @@ -0,0 +1,14 @@ +#!/usr/bin/env lua + +local constants = require "kong.constants" +local start = require "kong.cli.utils.start" +local stop = require "kong.cli.utils.stop" +local args = require("lapp")(string.format([[ +Usage: kong restart [options] + +Options: + -c,--config (default %s) configuration file +]], constants.CLI.GLOBAL_KONG_CONF)) + +stop(args.config) +start(args.config) diff --git a/src/cli/start.lua b/src/cli/start.lua index 21884949cb9..97c39131d24 100755 --- a/src/cli/start.lua +++ b/src/cli/start.lua @@ -1,7 +1,7 @@ #!/usr/bin/env lua -local cutils = require "kong.cli.utils" local constants = require "kong.constants" +local start = require "kong.cli.utils.start" local args = require("lapp")(string.format([[ Usage: kong start [options] @@ -9,45 +9,4 @@ Options: -c,--config (default %s) configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) --- Make sure nginx is there and is openresty -local nginx_path = cutils.find_nginx() -if not nginx_path then - cutils.logger:error_exit("can't find nginx") -end - --- Get configuration from default or given path -local config_path = cutils.get_kong_config_path(args.config) -local config, dao_factory = cutils.load_configuration_and_dao(config_path) - --- Migrate the DB if needed and possible -local keyspace, err = dao_factory:get_migrations() -if err then - cutils.logger:error_exit(err) -elseif keyspace == nil then - cutils.logger:log("Database not initialized. Running migrations...") - local migrations = require("kong.tools.migrations")(dao_factory) - 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)) - end - end) -end - --- Prepare nginx --prefix dir -local nginx_working_dir = cutils.prepare_nginx_working_dir(config) - --- Build nginx start command -local cmd = string.format("KONG_CONF=%s %s -p %s -c %s -g 'pid %s;'", - config_path, - nginx_path, - nginx_working_dir, - constants.CLI.NGINX_CONFIG, - constants.CLI.NGINX_PID) - -if os.execute(cmd) == 0 then - cutils.logger:success("Started") -else - cutils.logger:error_exit("Could not start Kong") -end +start(args.config) diff --git a/src/cli/stop.lua b/src/cli/stop.lua index 63f09fbec17..fb1ca377209 100755 --- a/src/cli/stop.lua +++ b/src/cli/stop.lua @@ -1,7 +1,7 @@ #!/usr/bin/env lua -local cutils = require "kong.cli.utils" local constants = require "kong.constants" +local stop = require "kong.cli.utils.stop" local args = require("lapp")(string.format([[ Usage: kong stop [options] @@ -9,18 +9,4 @@ Options: -c,--config (default %s) configuration file ]], constants.CLI.GLOBAL_KONG_CONF)) --- Get configuration from default or given path -local config_path = cutils.get_kong_config_path(args.config) -local config = cutils.load_configuration_and_dao(config_path) - -local pid = cutils.path:join(config.nginx_working_dir, constants.CLI.NGINX_PID) - -if not cutils.file_exists(pid) then - cutils.logger:error_exit("Not running. Could not find pid at: "..pid) -end - -local cmd = "kill -QUIT $(cat "..pid..")" - -if os.execute(cmd) == 0 then - cutils.logger:success("Stopped") -end +stop(args.config) diff --git a/src/cli/utils/start.lua b/src/cli/utils/start.lua new file mode 100644 index 00000000000..81827704baa --- /dev/null +++ b/src/cli/utils/start.lua @@ -0,0 +1,102 @@ +local IO = require "kong.tools.io" +local cutils = require "kong.cli.utils" +local constants = require "kong.constants" + +local _M = {} + +local function is_openresty(path_to_check) + local cmd = tostring(path_to_check).." -v 2>&1" + local handle = io.popen(cmd) + local out = handle:read() + handle:close() + local matched = out:match("^nginx version: ngx_openresty/") or out:match("^nginx version: openresty/") + if matched then + return path_to_check + end +end + +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 = tostring(prefix)..tostring(nginx_bin) + if is_openresty(to_check) then + return to_check + end + end +end + +local function prepare_nginx_working_dir(kong_config) + if kong_config.send_anonymous_reports then + kong_config.nginx = "error_log syslog:server=kong-hf.mashape.com:61828 error;\n"..kong_config.nginx + end + + -- Create nginx folder if needed + local _, err = IO.path:mkdir(IO.path:join(kong_config.nginx_working_dir, "logs")) + if err then + cutils.logger:error_exit(err) + end + os.execute("touch "..IO.path:join(kong_config.nginx_working_dir, "logs", "error.log")) + os.execute("touch "..IO.path:join(kong_config.nginx_working_dir, "logs", "access.log")) + + -- Extract nginx config to nginx folder + IO.write_to_file(IO.path:join(kong_config.nginx_working_dir, constants.CLI.NGINX_CONFIG), kong_config.nginx) + + return kong_config.nginx_working_dir +end + +function _M.start(args_config) + -- 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") + end + + -- Get configuration from default or given path + local config_path = cutils.get_kong_config_path(args_config) + local config, dao_factory = IO.load_configuration_and_dao(config_path) + + -- Migrate the DB if needed and possible + local keyspace, err = dao_factory:get_migrations() + if err then + cutils.logger:error_exit(err) + elseif keyspace == nil then + cutils.logger:log("Database not initialized. Running migrations...") + local migrations = require("kong.tools.migrations")(dao_factory) + 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)) + end + end) + end + + -- Prepare nginx --prefix dir + local nginx_working_dir = prepare_nginx_working_dir(config) + + -- Build nginx start command + local cmd = string.format("KONG_CONF=%s %s -p %s -c %s -g 'pid %s;'", + config_path, + nginx_path, + nginx_working_dir, + constants.CLI.NGINX_CONFIG, + constants.CLI.NGINX_PID) + + if os.execute(cmd) == 0 then + cutils.logger:success("Started") + else + cutils.logger:error_exit("Could not start Kong") + end + +end + +return _M.start diff --git a/src/cli/utils/stop.lua b/src/cli/utils/stop.lua new file mode 100644 index 00000000000..4ccb0724455 --- /dev/null +++ b/src/cli/utils/stop.lua @@ -0,0 +1,25 @@ +local IO = require "kong.tools.io" +local cutils = require "kong.cli.utils" +local constants = require "kong.constants" + +local _M = {} + +function _M.stop(args_config) + -- Get configuration from default or given path + local config_path = cutils.get_kong_config_path(args_config) + local config = IO.load_configuration_and_dao(config_path) + + local pid = IO.path:join(config.nginx_working_dir, constants.CLI.NGINX_PID) + + if not IO.file_exists(pid) then + cutils.logger:error_exit("Not running. Could not find pid at: "..pid) + end + + local cmd = "kill -QUIT $(cat "..pid..")" + + if os.execute(cmd) == 0 then + cutils.logger:success("Stopped") + end +end + +return _M.stop diff --git a/src/cli/utils.lua b/src/cli/utils/utils.lua similarity index 52% rename from src/cli/utils.lua rename to src/cli/utils/utils.lua index c8637bea714..6e05636772d 100644 --- a/src/cli/utils.lua +++ b/src/cli/utils/utils.lua @@ -1,16 +1,14 @@ --[[ Kong CLI utilities - - Colorization - Logging - - Disk I/O utils - - nginx path/initialization + - Luarocks helpers ]] -local lpath = require "luarocks.path" -local utils = require "kong.tools.utils" -local Object = require "classic" -local constants = require "kong.constants" local ansicolors = require "ansicolors" +local constants = require "kong.constants" +local Object = require "classic" +local lpath = require "luarocks.path" +local IO = require "kong.tools.io" -- -- Colors @@ -54,60 +52,11 @@ end local logger = Logger() -local function get_infos() - return { name = constants.NAME, version = constants.VERSION } -end - -- --- NGINX +-- Luarocks -- -local function is_openresty(path_to_check) - local cmd = tostring(path_to_check).." -v 2>&1" - local handle = io.popen(cmd) - local out = handle:read() - handle:close() - local matched = out:match("^nginx version: ngx_openresty/") or out:match("^nginx version: openresty/") - if matched then - return path_to_check - end -end - -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 = tostring(prefix)..tostring(nginx_bin) - if is_openresty(to_check) then - return to_check - end - end -end - -local function prepare_nginx_working_dir(kong_config) - if kong_config.send_anonymous_reports then - kong_config.nginx = "error_log syslog:server=kong-hf.mashape.com:61828 error;\n"..kong_config.nginx - end - - -- Create nginx folder if needed - local _, err = utils.path:mkdir(utils.path:join(kong_config.nginx_working_dir, "logs")) - if err then - logger:error_exit(err) - end - os.execute("touch "..utils.path:join(kong_config.nginx_working_dir, "logs", "error.log")) - os.execute("touch "..utils.path:join(kong_config.nginx_working_dir, "logs", "access.log")) - - -- Extract nginx config to nginx folder - utils.write_to_file(utils.path:join(kong_config.nginx_working_dir, constants.CLI.NGINX_CONFIG), kong_config.nginx) - - return kong_config.nginx_working_dir +local function get_infos() + return { name = constants.NAME, version = constants.VERSION } end local function get_luarocks_dir() @@ -146,23 +95,23 @@ end local function get_kong_config_path(args_config) -- Use the rock's config if no config at default location - if not utils.file_exists(args_config) then + if not IO.file_exists(args_config) then logger:warn("No config at: "..args_config.." using default config instead.") - args_config = utils.path:join(get_luarocks_config_dir(), "kong.yml") + args_config = IO.path:join(get_luarocks_config_dir(), "kong.yml") end -- Make sure the configuration file really exists - if not utils.file_exists(args_config) then + if not IO.file_exists(args_config) then logger:warn("No config at: "..args_config) logger:error_exit("Could not find a configuration file.") end - logger:log("Using config: "..args_config.."\n") + logger:log("Using config: "..args_config) -- TODO: validate configuration --[[local status, res = pcall(require, "kong.dao."..config.database..".factory") if not status then - cutils.logger:error("Wrong config") + logger:error("Wrong config") os.exit(1) end]] @@ -170,18 +119,9 @@ local function get_kong_config_path(args_config) end return { - path = utils.path, colors = colors, logger = logger, - get_infos = get_infos, - find_nginx = find_nginx, - is_openresty = is_openresty, - read_file = utils.read_file, - file_exists = utils.file_exists, - write_to_file = utils.write_to_file, get_kong_config_path = get_kong_config_path, - get_luarocks_install_dir = get_luarocks_install_dir, - prepare_nginx_working_dir = prepare_nginx_working_dir, - load_configuration_and_dao = utils.load_configuration_and_dao + get_luarocks_install_dir = get_luarocks_install_dir } diff --git a/src/kong.lua b/src/kong.lua index 370b44bfff9..b13d2773a70 100644 --- a/src/kong.lua +++ b/src/kong.lua @@ -25,6 +25,7 @@ -- ========== utils = require "kong.tools.utils" +local IO = require "kong.tools.io" local cache = require "kong.tools.cache" local constants = require "kong.constants" local timestamp = require "kong.tools.timestamp" @@ -136,7 +137,7 @@ end -- @return nil function _M.init() -- Loading configuration - configuration, dao = utils.load_configuration_and_dao(os.getenv("KONG_CONF")) + configuration, dao = IO.load_configuration_and_dao(os.getenv("KONG_CONF")) -- Initializing DAO local err = dao:prepare() diff --git a/src/tools/io.lua b/src/tools/io.lua new file mode 100644 index 00000000000..8eca95f9f0a --- /dev/null +++ b/src/tools/io.lua @@ -0,0 +1,85 @@ +local constants = require "kong.constants" +local path = require("path").new("/") +local yaml = require "yaml" + +local _M = {} + +_M.path = path + +function _M.read_file(path) + local contents = nil + local file = io.open(path, "rb") + if file then + contents = file:read("*all") + file:close() + end + return contents +end + +function _M.write_to_file(path, value) + local file = io.open(path, "w") + file:write(value) + file:close() +end + +function _M.file_exists(name) + local f = io.open(name, "r") + if f ~= nil then + io.close(f) + return true + else + return false + end +end + +function _M.retrieve_files(dir, options) + local fs = require "luarocks.fs" + local pattern = options.file_pattern + local exclude_dir_pattern = options.exclude_dir_pattern + + if not pattern then pattern = "" end + if not exclude_dir_pattern then exclude_dir_pattern = "" end + local files = {} + + local function tree(dir) + for _, file in ipairs(fs.list_dir(dir)) do + local f = path:join(dir, file) + if fs.is_dir(f) and string.match(f, exclude_dir_pattern) == nil then + tree(f) + elseif fs.is_file(f) and string.match(file, pattern) ~= nil then + table.insert(files, f) + end + end + end + + tree(dir) + + return files +end + +function _M.load_configuration_and_dao(configuration_path) + local configuration_file = _M.read_file(configuration_path) + if not configuration_file then + error("No configuration file at: "..configuration_path) + end + + -- Configuraiton should already be validated by the CLI at this point + local configuration = yaml.load(configuration_file) + + local dao_config = configuration.databases_available[configuration.database] + if dao_config == nil then + error("No dao \""..configuration.database.."\" defined") + end + + -- Adding computed properties to the configuration + configuration.pid_file = path:join(configuration.nginx_working_dir, constants.CLI.NGINX_PID) + + -- Instanciate the DAO Factory along with the configuration + local DaoFactory = require("kong.dao."..configuration.database..".factory") + local dao_factory = DaoFactory(dao_config.properties) + + return configuration, dao_factory +end + + +return _M diff --git a/src/tools/utils.lua b/src/tools/utils.lua index b1821b6b081..20bbabdf324 100644 --- a/src/tools/utils.lua +++ b/src/tools/utils.lua @@ -1,11 +1,7 @@ local constants = require "kong.constants" local cjson = require "cjson" -local yaml = require "yaml" -local path = require("path").new("/") -local _M = { - path = path -} +local _M = {} -- -- General utils @@ -96,87 +92,6 @@ function _M.add_error(errors, k, v) return errors end --- --- Disk I/O --- -function _M.read_file(path) - local contents = nil - local file = io.open(path, "rb") - if file then - contents = file:read("*all") - file:close() - end - return contents -end - -function _M.write_to_file(path, value) - local file = io.open(path, "w") - file:write(value) - file:close() -end - -function _M.file_exists(name) - local f = io.open(name, "r") - if f ~= nil then - io.close(f) - return true - else - return false - end -end - -function _M.retrieve_files(dir, options) - local fs = require "luarocks.fs" - local pattern = options.file_pattern - local exclude_dir_pattern = options.exclude_dir_pattern - - if not pattern then pattern = "" end - if not exclude_dir_pattern then exclude_dir_pattern = "" end - local files = {} - - local function tree(dir) - for _, file in ipairs(fs.list_dir(dir)) do - local f = path:join(dir, file) - if fs.is_dir(f) and string.match(f, exclude_dir_pattern) == nil then - tree(f) - elseif fs.is_file(f) and string.match(file, pattern) ~= nil then - table.insert(files, f) - end - end - end - - tree(dir) - - return files -end - --- --- DAO utils --- -function _M.load_configuration_and_dao(configuration_path) - local configuration_file = _M.read_file(configuration_path) - if not configuration_file then - error("No configuration file at: "..configuration_path) - end - - -- Configuraiton should already be validated by the CLI at this point - local configuration = yaml.load(configuration_file) - - local dao_config = configuration.databases_available[configuration.database] - if dao_config == nil then - error("No dao \""..configuration.database.."\" defined") - end - - -- Adding computed properties to the configuration - configuration.pid_file = path:join(configuration.nginx_working_dir, constants.CLI.NGINX_PID) - - -- Instanciate the DAO Factory along with the configuration - local DaoFactory = require("kong.dao."..configuration.database..".factory") - local dao_factory = DaoFactory(dao_config.properties) - - return configuration, dao_factory -end - -- -- Response utils --