remove not yet refactored plugins temporarily

This commit is contained in:
jysperm
2014-11-15 14:34:09 +08:00
parent e68aded965
commit 6e33ed2bb2
35 changed files with 0 additions and 1235 deletions

View File

@@ -1,17 +0,0 @@
child_process = require 'child_process'
service = require './service'
{requireInService} = require '../../core/middleware'
mAccount = require '../../core/model/account'
module.exports = exports = express.Router()
exports.use requireInService 'memcached'
exports.post '/switch', (req, res) ->
unless req.body.enable in [true, false]
return res.error 'invalid_enable'
service.switch req.account, req.body.enable, ->
res.json {}

View File

@@ -1,12 +0,0 @@
action = require './action'
service = require './service'
module.exports =
name: 'memcached'
type: 'service'
action: action
service: service
switch: true
switch_status: service.switch_status

View File

@@ -1,4 +0,0 @@
{
"name": "Memcached",
"description": "Memcached 提供了基于内存的高速缓存"
}

View File

@@ -1,41 +0,0 @@
child_process = require 'child_process'
jade = require 'jade'
path = require 'path'
tmp = require 'tmp'
fs = require 'fs'
plugin = require '../../core/pluggable'
monitor = require '../linux/monitor'
mAccount = require '../../core/model/account'
MEMCACHED_FLAGS = '-d -m 16'
module.exports =
enable: (account, callback) ->
callback()
delete: (account, callback) ->
callback()
switch: (account, is_enable, callback) ->
if is_enable
app.redis.del 'rp:process_list', =>
@switch_status account, (is_act_enable) ->
if is_act_enable
return callback()
child_process.exec pluggable.sudoSu(account, "memcached #{MEMCACHED_FLAGS} -s ~/memcached.sock"), (err) ->
throw err if err
app.redis.del 'rp:process_list', ->
callback()
else
child_process.exec pluggable.sudoSu(account, "pkill -exf -u #{account.username} \"memcached #{MEMCACHED_FLAGS} -s /home/#{account.username}/memcached.sock\""), ->
callback()
switch_status: (account, callback) ->
monitor.getProcessList (plist) ->
process = _.find plist, (i) ->
return i.user == account.username and i.command == "memcached #{MEMCACHED_FLAGS} -s /home/#{account.username}/memcached.sock"
callback if process then true else false

View File

@@ -1,65 +0,0 @@
crypto = require 'crypto'
{requireInService} = require '../../core/middleware'
mongodb = app.plugins.mongodb
mAccount = require '../../core/model/account'
module.exports = exports = express.Router()
exports.use requireInService 'mongodb'
exports.post '/update_password', (req, res) ->
unless req.body.password or /^[A-Za-z0-9\-_]+$/.test req.body.password
return res.error 'invalid_password'
md5 = crypto.createHash 'md5'
md5.update "#{req.account.username}:mongo:#{req.body.password}"
pwd = md5.digest 'hex'
mongodb.admin_users.update {user: req.account.username},
$set:
pwd: pwd
, (err, result) ->
mongodb.admin.listDatabases (err, result) ->
dbs = _.filter result.databases, (i) ->
return i.name[..req.account.username.length] == "#{req.account.username}_"
async.each dbs, (db, callback) ->
db_users = app.db.db(db.name).collection 'system.users'
db_users.update {user: req.account.username},
$set:
pwd: pwd
, ->
callback()
, ->
res.json {}
exports.post '/create_database', (req, res) ->
unless req.body.name[..req.account.username.length] == "#{req.account.username}_"
return res.error 'invalid_name'
unless /^[A-Za-z0-9_]+$/.test req.body.name
return res.error 'invalid_name'
mongodb.admin_users.findOne
user: req.account.username
, (err, result) ->
db_users = app.db.db(req.body.name).collection 'system.users'
db_users.insert
user: req.account.username
pwd: result.pwd
roles: ['readWrite', 'dbAdmin']
, (err) ->
res.json {}
exports.post '/delete_database', (req, res) ->
unless req.body.name[..req.account.username.length] == "#{req.account.username}_"
return res.error 'invalid_name'
unless /^[A-Za-z0-9_]+$/.test req.body.name
return res.error 'invalid_name'
app.db.db(req.body.name).dropDatabase ->
res.json {}

View File

@@ -1,15 +0,0 @@
app.plugins.mongodb = {}
action = require './action'
service = require './service'
module.exports =
name: 'mongodb'
type: 'service'
action: action
service: service
panel:
widget: service.widget
script: '/script/panel.js'

View File

@@ -1,4 +0,0 @@
{
"name": "MongoDB",
"description": "MongoDB 是世界上最流行的非关系型数据库之一"
}

View File

@@ -1,61 +0,0 @@
jade = require 'jade'
path = require 'path'
async = require 'async'
crypto = require 'crypto'
config = require '../../config'
mAccount = require '../../core/model/account'
mongodb = app.plugins.mongodb
mongodb.admin = app.db.admin()
mongodb.admin.authenticate config.mongodb.user, config.mongodb.password, ->
mongodb.admin_users = app.db.db('admin').collection 'system.users'
module.exports =
enable: (account, callback) ->
md5 = crypto.createHash 'md5'
md5.update "#{account.username}:mongo:#{mAccount.randomSalt()}"
pwd = md5.digest 'hex'
mongodb.admin_users.insert
user: account.username
pwd: pwd
roles: []
, (err, result) ->
callback()
delete: (account, callback) ->
mongodb.admin_users.remove
user: account.username
, (err) ->
mongodb.admin.listDatabases (err, result) ->
dbs = _.filter result.databases, (i) ->
return i.name[..account.username.length] == "#{account.username}_"
async.each dbs, (db, callback) ->
app.db.db(db.name).dropDatabase ->
callback()
, ->
callback()
widget: (account, callback) ->
mongodb.admin.listDatabases (err, result) ->
dbs = _.filter result.databases, (i) ->
return i.name[..account.username.length] == "#{account.username}_"
jade.renderFile path.join(__dirname, 'view/widget.jade'),
account: account
dbs: dbs
, (err, html) ->
callback html
storage: (account, callback) ->
mongodb.admin.listDatabases (err, result) ->
dbs = _.filter result.databases, (i) ->
return i.name[..account.username.length] == "#{account.username}_"
callback null, _.reduce dbs, (memo, db) ->
return memo + db.sizeOnDisk / 1024 / 1024
, 0

View File

@@ -1,34 +0,0 @@
$ ->
$('#widget-mongodb button.create-database').click ->
$.post '/plugin/mongodb/create_database', JSON.stringify
name: $(@).parents('.input-group').find('input').val()
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success ->
location.reload()
$('#widget-mongodb button.delete-database').click ->
if window.confirm 'Are you sure?'
$.post '/plugin/mongodb/delete_database', JSON.stringify
name: $(@).parents('tr').data 'name'
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success ->
location.reload()
$('#widget-mongodb button.update-password').click ->
$.post '/plugin/mongodb/update_password', JSON.stringify
password: $(@).parents('.input-group').find('input').val()
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success ->
location.reload()

View File

@@ -1,34 +0,0 @@
header MongoDB
.col-md-6
.panel.panel-success
.panel-heading
h3.panel-title 新建数据库
.panel-body
.input-group
input.form-control(value='#{account.username}_')
span.input-group-btn
button.create-database.btn.btn-default(type='button') 提交
.panel.panel-warning
.panel-heading
h3.panel-title 设置 MongoDB 密码
.panel-body
.input-group
input.form-control(type='password')
span.input-group-btn
button.update-password.btn.btn-default(type='button') 提交
.col-md-6
table(style= 'table-layout: fixed;').table.table-hover
thead
tr
td(style= 'width: 200px;') 数据库
td 磁盘占用
td
tbody
for db in dbs
tr(data-name= db.name)
td(style= 'white-space: nowrap; overflow: hidden;', title= db.name)= db.name
td #{(db.sizeOnDisk / 1024 / 1024).toFixed(1)}M
td
button.delete-database.btn.btn-danger.btn-xs
span.glyphicon.glyphicon-remove-sign

View File

@@ -1,19 +0,0 @@
mysql = require 'mysql'
plugin = require '../../core/pluggable'
{requireInService} = require '../../core/middleware'
connection = mysql.createConnection config.plugins.mysql.connection
connection.connect()
module.exports = exports = express.Router()
exports.use requireInService 'mysql'
exports.post '/update_password', (req, res) ->
unless req.body.password or /^[A-Za-z0-9\-_]+$/.test req.body.password
return res.error 'invalid_password'
connection.query "SET PASSWORD FOR '#{req.account.username}'@'localhost' = PASSWORD('#{req.body.password}');", (err, rows, fields) ->
throw err if err
res.json {}

View File

@@ -1,13 +0,0 @@
action = require './action'
service = require './service'
module.exports =
name: 'mysql'
type: 'service'
action: action
service: service
panel:
widget: service.widget
script: '/script/panel.js'

View File

@@ -1,4 +0,0 @@
{
"name": "MySQL",
"description": "MySQL 是世界上最流行的关系型数据库之一"
}

View File

@@ -1,54 +0,0 @@
jade = require 'jade'
path = require 'path'
mysql = require 'mysql'
async = require 'async'
config = require '../../config'
plugin = require '../../core/pluggable'
mAccount = require '../../core/model/account'
connection = mysql.createConnection config.plugins.mysql.connection
connection.connect()
module.exports =
enable: (account, callback) ->
connection.query "CREATE USER '#{account.username}'@'localhost' IDENTIFIED BY '#{mAccount.randomSalt()}';", (err, rows) ->
throw err if err
connection.query "GRANT ALL PRIVILEGES ON `#{account.username}\\_%%` . * TO '#{account.username}'@'localhost';", (err, rows) ->
throw err if err
callback()
delete: (account, callback) ->
connection.query "DROP USER '#{account.username}'@'localhost';", (err, rows) ->
throw err if err
connection.query "SHOW DATABASES LIKE '#{account.username}_%';", (err, rows) ->
throw err if err
databases_to_delete = _.filter _.pluck(rows, "Database (#{account.username}_%)"), (item) ->
if item[..account.username.length] == "#{account.username}_"
return true
else
return false
async.each databases_to_delete, (name, callback) ->
connection.query "DROP DATABASE `#{name}`;", (err, rows) ->
throw err if err
callback()
, ->
callback()
widget: (account, callback) ->
connection.query "SELECT `table_schema` 'name', sum(`data_length` + `index_length`) / 1024 / 1024 'size', sum(`data_free`) / 1024 / 1024 'free' FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE '#{account.username}_%' GROUP BY table_schema;", (err, rows) ->
jade.renderFile path.join(__dirname, 'view/widget.jade'),
dbs: rows
, (err, html) ->
callback html
storage: (account, callback) ->
connection.query "SELECT `table_schema` 'name', sum(`data_length` + `index_length`) / 1024 / 1024 'size', sum(`data_free`) / 1024 / 1024 'free' FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE '#{account.username}_%' GROUP BY table_schema;", (err, rows) ->
callback null, _.reduce rows, (memo, db) ->
return memo + db.size
, 0

View File

@@ -1,11 +0,0 @@
$ ->
$('#widget-mysql .update-password button').click ->
$.post '/plugin/mysql/update_password/', JSON.stringify
password: $('#widget-mysql .update-password input').val()
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success ->
location.reload()

View File

@@ -1,23 +0,0 @@
header MySQL
.col-md-6
.panel.panel-warning
.panel-heading
h3.panel-title 设置 MySQL 密码
.panel-body
.input-group.update-password
input.form-control(type='password')
span.input-group-btn
button.btn.btn-default(type='button') 提交
.col-md-6
table(style= 'table-layout: fixed;').table.table-hover
thead
tr
td(style= 'width: 200px;') 数据库
td 体积
td 磁盘占用
tbody
for db in dbs
tr
td(style= 'white-space: nowrap; overflow: hidden;', title= db.name)= db.name
td #{db.size.toFixed(1)}M
td #{(db.size + db.free).toFixed(1)}M

View File

@@ -1,100 +0,0 @@
child_process = require 'child_process'
service = require './service'
configure = require './configure'
{requireInService, getParam} = require '../../core/middleware'
mAccount = require '../../core/model/account'
module.exports = exports = express.Router()
exports.use requireInService 'nginx'
sample =
_id: '53c96734c2dad7d6208a0fbe'
is_enable: true
listen: 80
server_name: ['domain1', 'domain2']
auto_index: false
index: ['index.html', 'index.html']
root: '/home/user/web'
location:
'/':
try_files: ['$uri', '$uri/', '/index.php?$args']
'~ \\.php$':
fastcgi_pass: 'unix:///home/user/phpfpm.sock'
fastcgi_index: ['index.php']
include: 'fastcgi_params'
exports.all '/site_config', getParam, (req, res) ->
site = _.find req.account.attribute.plugin.nginx.sites, (i) ->
return i._id.toString() == req.body.id
site.id = site._id
delete site._id
res.json site
exports.post '/update_site', (req, res) ->
unless req.body.action in ['create', 'update', 'delete']
return res.error 'invalid_action'
checkSite = (callback) ->
if req.body.action == 'create'
callback null
else
mAccount.findOne
'attribute.plugin.nginx.sites._id': new ObjectID req.body.id
, (err, account) ->
if account?._id.toString() == req.account._id.toString()
callback null
else
callback true
checkSiteConfig = (callback) ->
unless req.body.action == 'delete'
if req.body.type == 'json'
configure.assert req.account, req.body.config, req.body.id, (err) ->
callback err
else
callback 'invalid_type'
else
callback null
checkSite (err) ->
if err
return res.error 'forbidden'
checkSiteConfig (err) ->
if err
return res.error err
removeSite = (callback) ->
mAccount.update _id: req.account._id,
$pull:
'attribute.plugin.nginx.sites':
'_id': new ObjectID req.body.id
, callback
addSite = (callback) ->
req.body.config._id = new ObjectID()
req.body.config = _.pick req.body.config, _.keys(sample)
mAccount.update _id: req.account._id,
$push:
'attribute.plugin.nginx.sites': req.body.config
, callback
execModification = (callback) ->
if req.body.action == 'create'
addSite callback
else if req.body.action == 'update'
removeSite ->
addSite callback
else if req.body.action == 'delete'
removeSite callback
execModification ->
service.writeConfig req.account, ->
res.json {}

View File

@@ -1,129 +0,0 @@
mAccount = require '../../core/model/account'
exports.checkHomeFilePath = (account, path) ->
home_dir = "/home/#{account.username}/"
unless /^[/A-Za-z0-9_\-\.]+\/?$/.test path
return false
unless path.slice(0, home_dir.length) == home_dir
return false
unless path.length < 512
return false
unless path.slice(-3) != '/..'
return false
unless path.indexOf('/../') == -1
return false
return true
exports.checkHomeUnixSocket = (account, path) ->
fastcgi_prefix = 'unix://'
unless path.slice(0, fastcgi_prefix.length) == fastcgi_prefix
return false
unless exports.checkHomeFilePath account, path.slice fastcgi_prefix.length
return false
return true
exports.assert = (account, config, site_id, callback) ->
config.index ?= ['index.html']
config.location ?= {}
unless config.is_enable == false
config.is_enable = true
unless config.listen in [80]
return callback 'invalid_listen'
async.each config.server_name, (domain, callback) ->
unless utils.rx.domain.test domain
return callback 'invalid_server_name'
mAccount.findOne
'attribute.plugin.nginx.sites.server_name': domain
, (err, result) ->
unless result
return callback null
site = _.find result.attribute.plugin.nginx.sites, (i) ->
return domain in i.server_name
if site._id.toString() == site_id?.toString()
callback null
else
callback 'unavailable_server_name'
, (err) ->
if err
return callback err
if config.auto_index
config.auto_index = if config.auto_index then true else false
unless _.isArray config.index
return callback 'invalid_index'
for file in config.index
unless utils.rx.filename.test file
return callback 'invalid_index'
if config.root
unless utils.checkHomeFilePath account, config.root
return callback 'invalid_root'
for path, rules of config.location
unless path in ['/', '~ \\.php$']
return callback 'invalid_location'
for name, value of rules
switch name
when 'fastcgi_pass'
rules['fastcgi_index'] ?= ['index.php']
unless utils.checkHomeUnixSocket account, value
return callback 'invalid_fastcgi_pass'
when 'uwsgi_pass'
unless utils.checkHomeUnixSocket account, value
return callback 'invalid_fastcgi_pass'
when 'proxy_pass'
rules['proxy_redirect'] ?= false
unless utils.checkHomeUnixSocket(account, value) or utils.rx.url.test value
return callback 'invalid_proxy_pass'
when 'proxy_set_header'
for header_name, header_value of value
switch header_name
when 'Host'
unless header_value == '$host' or utils.rx.domain.test header_value
return callback 'invalid_proxy_set_header'
else
return callback 'invalid_proxy_set_header'
when 'proxy_redirect'
rules['proxy_redirect'] = if value then true else false
when 'fastcgi_index'
for file in value
unless utils.rx.filename.test file
return callback 'invalid_fastcgi_index'
when 'include'
unless value in ['fastcgi_params', 'uwsgi_params']
return callback 'invalid_include'
when 'try_files'
for item in value
unless item in ['$uri', '$uri/', '/index.php?$args']
return callback 'invalid_try_files'
else
return callback 'unknown_command'
callback null

View File

@@ -1,14 +0,0 @@
action = require './action'
service = require './service'
module.exports =
name: 'nginx'
type: 'service'
action: action
service: service
panel:
widget: service.widget
script: '/script/panel.js'
style:'/style/panel.css'

View File

@@ -1,4 +0,0 @@
{
"name": "Nginx",
"description": "Nginx 提供了自定义系统 80 端口上的 Nginx 的配置的功能"
}

View File

@@ -1,82 +0,0 @@
child_process = require 'child_process'
jade = require 'jade'
path = require 'path'
fs = require 'fs'
plugin = require '../../core/pluggable'
mAccount = require '../../core/model/account'
template =
site_configure: fs.readFileSync("#{__dirname}/template/site_configure.conf").toString()
user_configure: fs.readFileSync("#{__dirname}/template/user_configure.conf").toString()
siteSummary = (site) ->
type = do ->
unless site['location']['/']
return 'static'
if site['location']['/']['proxy_pass']
return 'proxy'
if site['location']['/']['uwsgi_pass']
return 'uwsgi'
if site['location']['/']?['try_files']
for item in site['location']['/']['try_files']
if item.match(/\.php/)
return 'factcgi'
return 'static'
prefix = "(#{if site.is_enable then '' else 'x'}) #{type};"
switch type
when 'static', 'factcgi'
return "#{prefix} root: #{site['root']}"
when 'proxy'
return "#{prefix} url: " + site['location']['/']['proxy_pass']
when 'uwsgi'
return "#{prefix} socket: " + site['location']['/']['uwsgi_pass']
module.exports =
enable: (account, callback) ->
mAccount.update {_id: account._id},
$set:
'attribute.plugin.nginx.sites': []
, ->
callback()
delete: (account, callback) ->
child_process.exec "sudo rm /etc/nginx/sites-enabled/#{account.username}.conf", ->
callback()
writeConfig: (account, callback) ->
mAccount.findId account._id, (err, account) ->
unless account.attribute.plugin.nginx.sites
return callback()
sites_configure = []
for site in account.attribute.plugin.nginx.sites
if site.is_enable
sites_configure.push _.template template.site_configure,
site: site
user_configure = _.template template.user_configure,
sites: sites_configure
pluggable.writeConfig "/etc/nginx/sites-enabled/#{account.username}.conf", user_configure, ->
child_process.exec 'sudo service nginx reload', (err) ->
throw err if err
callback()
siteSummary: siteSummary
widget: (account, callback) ->
jade.renderFile path.join(__dirname, 'view/widget.jade'),
account: account
siteSummary: siteSummary
, (err, html) ->
throw err if err
callback html

View File

@@ -1,175 +0,0 @@
$ ->
syncToJSON = ->
username = $('.nav.navbar-nav.navbar-right li:first a').text()
try
config = JSON.parse($('#nginx-type-json textarea').val())
catch e
config = {}
config['listen'] ?= 80
config['is_enable'] = $('.option-is-enable input').prop('checked')
config['server_name'] = $('.option-server-name input').val().split ' '
switch $('.option-type :radio:checked').val()
when 'fastcgi'
config['root'] = $('.option-root input').val() or $('.option-root input').prop('placeholder')
config['index'] ?= ['index.php', 'index.html']
config['location'] ?= {}
config['location']['/'] =
try_files: ['$uri', '$uri/', '/index.php?$args']
config['location']['~ \\.php$'] =
fastcgi_pass: "unix:///home/#{username}/phpfpm.sock"
include: 'fastcgi_params'
when 'proxy'
config['location'] ?= {}
config['location']['/'] =
proxy_pass: $('.option-proxy input').val() or $('.option-proxy input').prop('placeholder')
proxy_set_header:
Host: '$host'
when 'uwsgi'
config['location'] ?= {}
config['location']['/'] =
uwsgi_pass: $('.option-uwsgi input').val() or $('.option-uwsgi input').prop('placeholder')
include: 'uwsgi_params'
when 'static'
config['index'] ?= ['index.html']
config['root'] = $('.option-root input').val() or $('.option-root input').prop('placeholder')
$('#nginx-type-json textarea').val JSON.stringify(config, null, ' ')
return config
syncToGuide = ->
$('.json-error').parent().addClass 'hide'
try
config = JSON.parse($('#nginx-type-json textarea').val())
catch e
return
$('.option-is-enable input').prop 'checked', config['is_enable']
$('.option-server-name input').val config['server_name']?.join ' '
$('.option-root input').val config['root']
type = do ->
unless config['location']['/']
return 'static'
if config['location']['/']['proxy_pass']
return 'proxy'
if config['location']['/']['uwsgi_pass']
return 'uwsgi'
if config['location']['/']?['try_files']
for item in config['location']['/']['try_files']
if item.match(/\.php/)
return 'factcgi'
return 'static'
$("#nginx-modal :radio[value=#{type}]").click()
switch type
when 'proxy'
$('.option-proxy input').val config['location']['/']['proxy_pass']
when 'uwsgi'
$('.option-uwsgi input').val config['location']['/']['uwsgi_pass']
when 'static', 'fastcgi'
$('.option-root input').val config['root']
$('#nginx-type-json textarea').on 'change keyup paste', ->
try
JSON.parse($('#nginx-type-json textarea').val())
$('.json-error').parent().addClass 'hide'
catch err
console.log err
$('.json-error').text err.toString()
$('.json-error').parent().removeClass 'hide'
$('#nginx-modal ul li a').click ->
switch $(@).prop('href').match(/.*#nginx-type-(.*)/)[1]
when 'json'
syncToJSON()
when 'guide'
syncToGuide()
$('#nginx-modal .radio input').click ->
options = ['root', 'proxy', 'uwsgi']
mapping_table =
fastcgi: ['root']
proxy: ['proxy']
uwsgi: ['uwsgi']
static: ['root']
options_to_show = mapping_table[$(@).val()]
for item in options
if item in options_to_show
$("#nginx-modal .option-#{item}").removeClass 'hide'
else
$("#nginx-modal .option-#{item}").addClass 'hide'
$('#nginx-modal .modal-footer button.btn-success').click ->
type = $('#nginx-modal ul.config-type').find('.active a').prop('href').match(/.*#nginx-type-(.*)/)[1]
if type == 'guide'
config = syncToJSON()
else if type == 'json'
try
config = JSON.parse($('#nginx-type-json textarea').val())
catch e
return alert 'Invalid JSON'
else
return alert 'Coming Soon'
$.post '/plugin/nginx/update_site/', JSON.stringify
action: if config.id then 'update' else 'create'
id: config.id
type: 'json'
config: config
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.done ->
location.reload()
$('#widget-nginx table .btn-danger').click ->
if window.confirm 'Are you sure?'
$.post '/plugin/nginx/update_site', JSON.stringify
action: 'delete'
id: $(@).parents('tr').data 'id'
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success ->
location.reload()
$('#widget-nginx table .btn-success').click ->
$('#nginx-modal .site-id').text ''
$('#widget-nginx table button.btn-info').click ->
$.post '/plugin/nginx/site_config', JSON.stringify
id: $(@).parents('tr').data 'id'
.fail (jqXHR) ->
if jqXHR.responseJSON?.error
alert jqXHR.responseJSON.error
else
alert jqXHR.statusText
.success (data) ->
$('#nginx-type-json textarea').val JSON.stringify(data, null, ' ')
syncToGuide()
$('#nginx-modal .site-id').text data.id
$('#nginx-modal').modal 'show'

View File

@@ -1,21 +0,0 @@
#nginx-type-json {
textarea {
font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
font-size: 16px;
}
}
.tab-pane p {
margin: 15px;
}
.tab-pane {
padding-top: 15px;
}
@media (min-width: 768px) {
.modal-dialog {
width: 800px;
margin: 80px auto;
}
}

View File

@@ -1,29 +0,0 @@
server {
listen <%= site.listen %>;
server_name <%= site.server_name.join(' ') %>;
index <%= site.index.join(' ') %>;
autoindex <%= site.auto_index ? 'on' : 'off' %>;
<% if(site.root) { %>
root <%= site.root %>;
<% } %>
<% _.each(site.location, function(rules, path) { %>
location <%= path %> {
<% _.each(rules, function(param, command) { %>
<% if(_.isArray(param)) { %>
<%= command %> <%= param.join(' ') %>;
<% } else if(_.isBoolean(param)) { %>
<%= command %> <%= param ? 'on' : 'off' %>;
<% } else if(_.isObject(param)) { %>
<% _.each(param, function(param2, param1) { %>
<%= command %> <%= param1 %> <%= param2 %>;
<% }); %>
<% } else { %>
<%= command %> <%= param %>;
<% } %>
<% }); %>
}
<% }); %>
}

View File

@@ -1,3 +0,0 @@
<% _.each(sites, function(site) { %>
<%= site %>
<% }) %>

View File

@@ -1,97 +0,0 @@
header Nginx
table.table.table-hover
thead
tr
th 域名
th 摘要
th
button.btn.btn-success.btn-xs(data-toggle='modal', data-target='#nginx-modal')
span.glyphicon.glyphicon-plus-sign
tbody
for site in account.attribute.plugin.nginx.sites
tr(data-id= '#{site._id}')
td= site.server_name.join(', ')
td= siteSummary(site)
td(style= 'width: 150px;')
button.btn.btn-info.btn-xs
span.glyphicon.glyphicon-edit
button.btn.btn-danger.btn-xs
span.glyphicon.glyphicon-trash
.modal.fade#nginx-modal(tabindex='-1', role='dialog', aria-hidden='true')
.modal-dialog
.modal-content
.modal-header
button.close(type='button', data-dismiss='modal', aria-hidden='true') &times;
h3.modal-title
| Nginx &nbsp;
span.small.site-id
.modal-body
ul.nav.nav-tabs.config-type
li.active
a(href='#nginx-type-guide', data-toggle='tab') 向导
li
a(href='#nginx-type-json', data-toggle='tab') JSON
li
a(href='#nginx-type-original', data-toggle='tab') 原生
.tab-content
.tab-pane.active#nginx-type-guide
form.form-horizontal(role='form')
h3 常规
.form-group.option-is-enable
label.col-sm-2.control-label »
.checkbox.col-sm-10
label
input(type='checkbox', checked)
| 启用站点
.form-group.option-server-name
label.col-sm-2.control-label 域名
.col-sm-10
input.form-control(type='text', required, placeholder='example.com example.net')
h3 类型
.form-group.option-type
label.col-sm-2.control-label »
.controls.col-sm-10
.radio
label
input(type='radio', name='site-type', value='fastcgi', checked)
| fastcgi (PHP)
.radio
label
input(type='radio', name='site-type', value='proxy')
| proxy (反向代理)
.radio
label
input(type='radio', name='site-type', value='uwsgi')
| uwsgi (Python)
.radio
label
input(type='radio', name='site-type', value='static')
| static (静态文件)
h3 选项
.form-group.option-root
label.col-sm-2.control-label 根目录
.col-sm-10
input.form-control(type='text', placeholder='/home/#{account.username}/web')
.form-group.option-proxy.hide
label.col-sm-2.control-label 源地址
.col-sm-10
input.form-control(type='text', placeholder='http://127.0.0.1')
.form-group.option-uwsgi.hide
label.col-sm-2.control-label 源地址
.col-sm-10
input.form-control(type='text', placeholder='/home/#{account.username}/uwsgi.sock')
.tab-pane#nginx-type-json
form(role='form')
textarea.form-control(rows='18')
.tab-pane#nginx-type-original
p 即将支持
.modal-footer
p.pull-left.hide
span.glyphicon.glyphicon-warning-sign
| &nbsp;
span.json-error.text-danger 错误信息
button.btn.btn-success(type='button') 保存

View File

@@ -1,21 +0,0 @@
child_process = require 'child_process'
service = require './service'
{requireInService} = require '../../core/middleware'
mAccount = require '../../core/model/account'
module.exports = exports = express.Router()
exports.use requireInService 'phpfpm'
exports.post '/switch', (req, res) ->
unless req.body.enable in [true, false]
return res.error 'invalid_enable'
mAccount.update _id: req.account._id,
$set:
'attribute.plugin.phpfpm.is_enable': req.body.enable
, ->
service.switch req.account, req.body.enable, ->
res.json {}

View File

@@ -1,11 +0,0 @@
action = require './action'
service = require './service'
module.exports =
name: 'phpfpm'
type: 'service'
action: action
service: service
switch: true

View File

@@ -1,4 +0,0 @@
{
"name": "PHP-FPM",
"description": "PHP-FPM 提供了运行 PHP 程序的能力"
}

View File

@@ -1,39 +0,0 @@
child_process = require 'child_process'
jade = require 'jade'
path = require 'path'
tmp = require 'tmp'
fs = require 'fs'
plugin = require '../../core/pluggable'
mAccount = require '../../core/model/account'
module.exports =
enable: (account, callback) ->
mAccount.update {_id: account._id},
$set:
'attribute.plugin.phpfpm.is_enable': false
, ->
callback()
delete: (account, callback) ->
if account.attribute.plugin.phpfpm.is_enable
this.switch account, false, callback
else
callback()
switch: (account, is_enable, callback) ->
restartPhpfpm = ->
child_process.exec 'sudo service php5-fpm restart', (err) ->
throw err if err
callback()
if is_enable
config_content = _.template (fs.readFileSync path.join(__dirname, 'template/fpm-pool.conf')).toString(),
account: account
pluggable.writeConfig "/etc/php5/fpm/pool.d/#{account.username}.conf", config_content, ->
restartPhpfpm()
else
child_process.exec "sudo rm /etc/php5/fpm/pool.d/#{account.username}.conf", ->
restartPhpfpm()

View File

@@ -1,23 +0,0 @@
[<%= account.username %>]
user = <%= account.username %>
group = <%= account.username %>
listen = /home/<%= account.username %>/phpfpm.sock
listen.owner = <%= account.username %>
listen.group = <%= account.username %>
listen.mode = 0660
pm = ondemand
pm.max_children = 3
pm.process_idle_timeout = 10s
pm.max_requests = 500
slowlog = /home/<%= account.username %>/phpfpm.slowlog
request_slowlog_timeout = 5s
request_terminate_timeout = 15s
php_admin_value[memory_limit] = 128M
php_admin_value[error_log] = /home/<%= account.username %>/phpfpm_error.log
php_admin_flag[log_errors] = On

View File

@@ -1,17 +0,0 @@
child_process = require 'child_process'
service = require './service'
{requireInService} = require '../../core/middleware'
mAccount = require '../../core/model/account'
module.exports = exports = express.Router()
exports.use requireInService 'redis'
exports.post '/switch', (req, res) ->
unless req.body.enable in [true, false]
return res.error 'invalid_enable'
service.switch req.account, req.body.enable, ->
res.json {}

View File

@@ -1,12 +0,0 @@
action = require './action'
service = require './service'
module.exports =
name: 'redis'
type: 'service'
action: action
service: service
switch: true
switch_status: service.switch_status

View File

@@ -1,4 +0,0 @@
{
"name": "Redis",
"description": "Redis 提供了更灵活的缓存方案"
}

View File

@@ -1,39 +0,0 @@
child_process = require 'child_process'
jade = require 'jade'
path = require 'path'
tmp = require 'tmp'
fs = require 'fs'
plugin = require '../../core/pluggable'
monitor = require '../linux/monitor'
mAccount = require '../../core/model/account'
module.exports =
enable: (account, callback) ->
callback()
delete: (account, callback) ->
callback()
switch: (account, is_enable, callback) ->
if is_enable
app.redis.del 'rp:process_list', =>
@switch_status account, (is_act_enable) ->
if is_act_enable
return callback()
child_process.exec pluggable.sudoSu(account, 'redis-server --unixsocket ~/redis.sock --port 0 --daemonize yes'), (err) ->
throw err if err
app.redis.del 'rp:process_list', ->
callback()
else
child_process.exec pluggable.sudoSu(account, "pkill -ef -u #{account.username} redis-server"), ->
callback()
switch_status: (account, callback) ->
monitor.getProcessList (plist) ->
process = _.find plist, (i) ->
return i.user == account.username and i.command.trim() == 'redis-server *:0'
callback if process then true else false