Commit 7e0f1a57 by Torkel Ödegaard

Progress on deb and rpm packaging, renamed config files, added file logging, #1476

parent f5cd3d85
...@@ -11,22 +11,6 @@ module.exports = function (grunt) { ...@@ -11,22 +11,6 @@ module.exports = function (grunt) {
docsDir: 'docs/' docsDir: 'docs/'
}; };
config.mode = grunt.option('mode') || 'backend';
config.modeOptions = {
zipSuffix: '',
requirejs: {
paths: { config: '../config.sample' },
excludeConfig: true,
}
};
if (config.mode === 'backend') {
grunt.log.writeln('Setting backend build mode');
config.modeOptions.zipSuffix = '-backend';
config.modeOptions.requirejs.paths = {};
config.modeOptions.requirejs.excludeConfig = false;
}
// load plugins // load plugins
require('load-grunt-tasks')(grunt); require('load-grunt-tasks')(grunt);
......
...@@ -30,7 +30,7 @@ var ( ...@@ -30,7 +30,7 @@ var (
workingDir string workingDir string
installRoot = "/opt/grafana" installRoot = "/opt/grafana"
configRoot = "/etc/grafana" configRoot = "/etc/opt/grafana"
grafanaLogDir = "/var/log/grafana" grafanaLogDir = "/var/log/grafana"
) )
...@@ -115,9 +115,14 @@ func createRpmAndDeb() { ...@@ -115,9 +115,14 @@ func createRpmAndDeb() {
postInstallScriptPath, _ := ioutil.TempFile("", "postinstall") postInstallScriptPath, _ := ioutil.TempFile("", "postinstall")
versionFolder := filepath.Join(packageRoot, installRoot, "versions", version) versionFolder := filepath.Join(packageRoot, installRoot, "versions", version)
configDir := filepath.Join(packageRoot, configRoot)
runError("mkdir", "-p", versionFolder) runError("mkdir", "-p", versionFolder)
runError("mkdir", "-p", filepath.Join(packageRoot, configRoot)) runError("mkdir", "-p", configDir)
// copy sample ini file to /etc/opt/grafana
runError("cp", "conf/sample.ini", filepath.Join(configDir, "grafana.ini"))
// copy release files
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", versionFolder) runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", versionFolder)
fmt.Printf("PackageDir: %v\n", versionFolder) fmt.Printf("PackageDir: %v\n", versionFolder)
...@@ -268,7 +273,7 @@ func clean() { ...@@ -268,7 +273,7 @@ func clean() {
rmr("bin", "Godeps/_workspace/pkg", "Godeps/_workspace/bin") rmr("bin", "Godeps/_workspace/pkg", "Godeps/_workspace/bin")
rmr("dist") rmr("dist")
rmr("tmp") rmr("tmp")
rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafan", goos, goarch))) rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
} }
func setBuildEnv() { func setBuildEnv() {
......
app_mode = development
[server]
router_logging = false
static_root_path = src
[log]
level = Trace
mode = console, file
...@@ -30,7 +30,7 @@ ssl_mode = disable ...@@ -30,7 +30,7 @@ ssl_mode = disable
path = data/grafana.db path = data/grafana.db
[session] [session]
; Either "memory", "file", default is "memory" ; Either "memory", "file", "redis", "mysql", default is "memory"
provider = file provider = file
; Provider config options ; Provider config options
; memory: not have any config yet ; memory: not have any config yet
...@@ -100,8 +100,8 @@ auth_url = https://accounts.google.com/o/oauth2/auth ...@@ -100,8 +100,8 @@ auth_url = https://accounts.google.com/o/oauth2/auth
token_url = https://accounts.google.com/o/oauth2/token token_url = https://accounts.google.com/o/oauth2/token
[log] [log]
root_path = root_path = data/log
; Either "console", "file", "conn", "smtp" or "database", default is "console" ; Either "console", "file", default is "console"
; Use comma to separate multiple modes, e.g. "console, file" ; Use comma to separate multiple modes, e.g. "console, file"
mode = console mode = console
; Buffer length of channel, keep it as it is if you don't know what it is. ; Buffer length of channel, keep it as it is if you don't know what it is.
......
# Sample grafana config
# You only need to specify overrides here
# Defaults are in the /opt/grafana/current/conf/defaults.ini file
# This file is never ovewritten when upgrading grafana via deb or rpm package
app_mode = production
[server]
; protocol (http or https)
protocol = http
; the ip address to bind to, empty will bind to all interfaces
http_addr =
; the http port to use
http_port = 3000
; The public facing domain name used to access grafana from a browser
domain = localhost
; the full public facing url
root_url = %(protocol)s://%(domain)s:%(http_port)s/
router_logging = false
; the path relative to grafana process working directory
static_root_path = public
enable_gzip = false
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
type = sqlite3
host = 127.0.0.1:3306
name = grafana
user = root
password =
; For "postgres" only, either "disable", "require" or "verify-full"
ssl_mode = disable
; For "sqlite3" only
path = /opt/grafana/data/grafana.db
[log]
level = Trace
mode = console, file
root_path = /var/log/grafana
package cmd package cmd
import ( import (
"time"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
func initRuntime(c *cli.Context) { func initRuntime(c *cli.Context) {
setting.NewConfigContext(c.GlobalString("config")) setting.NewConfigContext(c.GlobalString("config"))
log.Info("Starting Grafana")
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
setting.LogLoadedConfigFiles()
sqlstore.NewEngine() sqlstore.NewEngine()
sqlstore.EnsureAdminUser() sqlstore.EnsureAdminUser()
} }
...@@ -7,7 +7,6 @@ import ( ...@@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"path" "path"
"time"
"github.com/Unknwon/macaron" "github.com/Unknwon/macaron"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
...@@ -68,9 +67,6 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) { ...@@ -68,9 +67,6 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) {
} }
func runWeb(c *cli.Context) { func runWeb(c *cli.Context) {
log.Info("Starting Grafana")
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
initRuntime(c) initRuntime(c)
social.NewOAuthService() social.NewOAuthService()
......
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
// FileLogWriter implements LoggerInterface.
// It writes messages by lines limit, file size limit, or time frequency.
type FileLogWriter struct {
*log.Logger
mw *MuxWriter
// The opened file
Filename string `json:"filename"`
Maxlines int `json:"maxlines"`
maxlines_curlines int
// Rotate at size
Maxsize int `json:"maxsize"`
maxsize_cursize int
// Rotate daily
Daily bool `json:"daily"`
Maxdays int64 `json:"maxdays"`
daily_opendate int
Rotate bool `json:"rotate"`
startLock sync.Mutex // Only one log can write to the file
Level int `json:"level"`
}
// an *os.File writer with locker.
type MuxWriter struct {
sync.Mutex
fd *os.File
}
// write to os.File.
func (l *MuxWriter) Write(b []byte) (int, error) {
l.Lock()
defer l.Unlock()
return l.fd.Write(b)
}
// set os.File in writer.
func (l *MuxWriter) SetFd(fd *os.File) {
if l.fd != nil {
l.fd.Close()
}
l.fd = fd
}
// create a FileLogWriter returning as LoggerInterface.
func NewFileWriter() LoggerInterface {
w := &FileLogWriter{
Filename: "",
Maxlines: 1000000,
Maxsize: 1 << 28, //256 MB
Daily: true,
Maxdays: 7,
Rotate: true,
Level: TRACE,
}
// use MuxWriter instead direct use os.File for lock write when rotate
w.mw = new(MuxWriter)
// set MuxWriter as Logger's io.Writer
w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime)
return w
}
// Init file logger with json config.
// config like:
// {
// "filename":"log/gogs.log",
// "maxlines":10000,
// "maxsize":1<<30,
// "daily":true,
// "maxdays":15,
// "rotate":true
// }
func (w *FileLogWriter) Init(config string) error {
if err := json.Unmarshal([]byte(config), w); err != nil {
return err
}
if len(w.Filename) == 0 {
return errors.New("config must have filename")
}
return w.StartLogger()
}
// start file logger. create log file and set to locker-inside file writer.
func (w *FileLogWriter) StartLogger() error {
fd, err := w.createLogFile()
if err != nil {
return err
}
w.mw.SetFd(fd)
if err = w.initFd(); err != nil {
return err
}
return nil
}
func (w *FileLogWriter) docheck(size int) {
w.startLock.Lock()
defer w.startLock.Unlock()
if w.Rotate && ((w.Maxlines > 0 && w.maxlines_curlines >= w.Maxlines) ||
(w.Maxsize > 0 && w.maxsize_cursize >= w.Maxsize) ||
(w.Daily && time.Now().Day() != w.daily_opendate)) {
if err := w.DoRotate(); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
return
}
}
w.maxlines_curlines++
w.maxsize_cursize += size
}
// write logger message into file.
func (w *FileLogWriter) WriteMsg(msg string, skip, level int) error {
if level < w.Level {
return nil
}
n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] "
w.docheck(n)
w.Logger.Println(msg)
return nil
}
func (w *FileLogWriter) createLogFile() (*os.File, error) {
// Open the log file
return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
}
func (w *FileLogWriter) initFd() error {
fd := w.mw.fd
finfo, err := fd.Stat()
if err != nil {
return fmt.Errorf("get stat: %s\n", err)
}
w.maxsize_cursize = int(finfo.Size())
w.daily_opendate = time.Now().Day()
if finfo.Size() > 0 {
content, err := ioutil.ReadFile(w.Filename)
if err != nil {
return err
}
w.maxlines_curlines = len(strings.Split(string(content), "\n"))
} else {
w.maxlines_curlines = 0
}
return nil
}
// DoRotate means it need to write file in new file.
// new file name like xx.log.2013-01-01.2
func (w *FileLogWriter) DoRotate() error {
_, err := os.Lstat(w.Filename)
if err == nil { // file exists
// Find the next available number
num := 1
fname := ""
for ; err == nil && num <= 999; num++ {
fname = w.Filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num)
_, err = os.Lstat(fname)
}
// return error if the last file checked still existed
if err == nil {
return fmt.Errorf("rotate: cannot find free log number to rename %s\n", w.Filename)
}
// block Logger's io.Writer
w.mw.Lock()
defer w.mw.Unlock()
fd := w.mw.fd
fd.Close()
// close fd before rename
// Rename the file to its newfound home
if err = os.Rename(w.Filename, fname); err != nil {
return fmt.Errorf("Rotate: %s\n", err)
}
// re-start logger
if err = w.StartLogger(); err != nil {
return fmt.Errorf("Rotate StartLogger: %s\n", err)
}
go w.deleteOldLog()
}
return nil
}
func (w *FileLogWriter) deleteOldLog() {
dir := filepath.Dir(w.Filename)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) (returnErr error) {
defer func() {
if r := recover(); r != nil {
returnErr = fmt.Errorf("Unable to delete old log '%s', error: %+v", path, r)
}
}()
if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.Maxdays) {
if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) {
os.Remove(path)
}
}
return returnErr
})
}
// destroy file logger, close file writer.
func (w *FileLogWriter) Destroy() {
w.mw.fd.Close()
}
// flush file logger.
// there are no buffering messages in file logger in memory.
// flush file means sync file from disk.
func (w *FileLogWriter) Flush() {
w.mw.fd.Sync()
}
func init() {
Register("file", NewFileWriter)
}
2015/03/03 09:52:42 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
2015/03/03 09:59:43 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
2015/03/03 10:03:13 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
2015/03/03 10:09:13 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
2015/03/03 10:09:34 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
2015/03/03 10:15:20 [I] Setting: ENV override found: GF_SECURITY_ADMIN_USER
...@@ -94,6 +94,8 @@ var ( ...@@ -94,6 +94,8 @@ var (
// PhantomJs Rendering // PhantomJs Rendering
ImagesDir string ImagesDir string
PhantomDir string PhantomDir string
configFiles []string
) )
func init() { func init() {
...@@ -102,30 +104,32 @@ func init() { ...@@ -102,30 +104,32 @@ func init() {
WorkDir, _ = filepath.Abs(".") WorkDir, _ = filepath.Abs(".")
} }
func findConfigFiles() []string { func findConfigFiles(customConfigFile string) {
ConfRootPath = path.Join(WorkDir, "conf") ConfRootPath = path.Join(WorkDir, "conf")
filenames := make([]string, 0) configFiles = make([]string, 0)
configFile := path.Join(ConfRootPath, "grafana.ini") configFile := path.Join(ConfRootPath, "defaults.ini")
if com.IsFile(configFile) { if com.IsFile(configFile) {
filenames = append(filenames, configFile) configFiles = append(configFiles, configFile)
} }
configFile = path.Join(ConfRootPath, "grafana.dev.ini") configFile = path.Join(ConfRootPath, "dev.ini")
if com.IsFile(configFile) { if com.IsFile(configFile) {
filenames = append(filenames, configFile) configFiles = append(configFiles, configFile)
} }
configFile = path.Join(ConfRootPath, "grafana.custom.ini") configFile = path.Join(ConfRootPath, "custom.ini")
if com.IsFile(configFile) { if com.IsFile(configFile) {
filenames = append(filenames, configFile) configFiles = append(configFiles, configFile)
} }
if len(filenames) == 0 { if customConfigFile != "" {
log.Fatal(3, "Could not find any config file") configFiles = append(configFiles, customConfigFile)
} }
return filenames if len(configFiles) == 0 {
log.Fatal(3, "Could not find any config file")
}
} }
func parseAppUrlAndSubUrl(section *ini.Section) (string, string) { func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
...@@ -165,11 +169,7 @@ func loadEnvVariableOverrides() { ...@@ -165,11 +169,7 @@ func loadEnvVariableOverrides() {
} }
func NewConfigContext(config string) { func NewConfigContext(config string) {
configFiles := findConfigFiles() findConfigFiles(config)
if config != "" {
configFiles = append(configFiles, config)
}
var err error var err error
...@@ -186,6 +186,7 @@ func NewConfigContext(config string) { ...@@ -186,6 +186,7 @@ func NewConfigContext(config string) {
} }
loadEnvVariableOverrides() loadEnvVariableOverrides()
initLogging()
AppName = Cfg.Section("").Key("app_name").MustString("Grafana") AppName = Cfg.Section("").Key("app_name").MustString("Grafana")
Env = Cfg.Section("").Key("app_mode").MustString("development") Env = Cfg.Section("").Key("app_mode").MustString("development")
...@@ -233,8 +234,6 @@ func NewConfigContext(config string) { ...@@ -233,8 +234,6 @@ func NewConfigContext(config string) {
ImagesDir = "data/png" ImagesDir = "data/png"
PhantomDir = "vendor/phantomjs" PhantomDir = "vendor/phantomjs"
LogRootPath = Cfg.Section("log").Key("root_path").MustString(path.Join(WorkDir, "/data/log"))
readSessionConfig() readSessionConfig()
} }
...@@ -253,3 +252,76 @@ func readSessionConfig() { ...@@ -253,3 +252,76 @@ func readSessionConfig() {
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm) os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
} }
} }
var logLevels = map[string]string{
"Trace": "0",
"Debug": "1",
"Info": "2",
"Warn": "3",
"Error": "4",
"Critical": "5",
}
func initLogging() {
// Get and check log mode.
LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",")
LogRootPath = Cfg.Section("log").Key("root_path").MustString(path.Join(WorkDir, "/data/log"))
LogConfigs = make([]string, len(LogModes))
for i, mode := range LogModes {
mode = strings.TrimSpace(mode)
sec, err := Cfg.GetSection("log." + mode)
if err != nil {
log.Fatal(4, "Unknown log mode: %s", mode)
}
// Log level.
levelName := Cfg.Section("log."+mode).Key("level").In("Trace",
[]string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
level, ok := logLevels[levelName]
if !ok {
log.Fatal(4, "Unknown log level: %s", levelName)
}
// Generate log configuration.
switch mode {
case "console":
LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level)
case "file":
logPath := sec.Key("file_name").MustString(path.Join(LogRootPath, "grafana.log"))
os.MkdirAll(path.Dir(logPath), os.ModePerm)
LogConfigs[i] = fmt.Sprintf(
`{"level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d}`, level,
logPath,
sec.Key("log_rotate").MustBool(true),
sec.Key("max_lines").MustInt(1000000),
1<<uint(sec.Key("max_size_shift").MustInt(28)),
sec.Key("daily_rotate").MustBool(true),
sec.Key("max_days").MustInt(7))
case "conn":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level,
sec.Key("reconnect_on_msg").MustBool(),
sec.Key("reconnect").MustBool(),
sec.Key("protocol").In("tcp", []string{"tcp", "unix", "udp"}),
sec.Key("addr").MustString(":7020"))
case "smtp":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"}`, level,
sec.Key("user").MustString("example@example.com"),
sec.Key("passwd").MustString("******"),
sec.Key("host").MustString("127.0.0.1:25"),
sec.Key("receivers").MustString("[]"),
sec.Key("subject").MustString("Diagnostic message from serve"))
case "database":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level,
sec.Key("driver").String(),
sec.Key("conn").String())
}
log.NewLogger(Cfg.Section("log").Key("buffer_len").MustInt64(10000), mode, LogConfigs[i])
}
}
func LogLoadedConfigFiles() {
for _, file := range configFiles {
log.Info("Config: Loaded from %s", file)
}
}
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
DAEMON_NAME="grafana" DAEMON_NAME="grafana"
DAEMON_USER="grafana" DAEMON_USER="grafana"
DAEMON_PATH="/opt/grafana/current/grafana" DAEMON_PATH="/opt/grafana/current/grafana"
DAEMON_OPTS="web" DAEMON_OPTS="--config=/etc/opt/grafana/grafana.ini web"
DAEMON_PWD="/opt/grafana/current" DAEMON_PWD="/opt/grafana/current"
DAEMON_PID="/var/run/${DAEMON_NAME}.pid" DAEMON_PID="/var/run/${DAEMON_NAME}.pid"
DAEMON_NICE=0 DAEMON_NICE=0
......
require.config({
urlArgs: 'bust=' + (new Date().getTime()),
baseUrl: 'app',
paths: {
config: ['../config', '../config.sample'],
settings: 'components/settings',
kbn: 'components/kbn',
store: 'components/store',
css: '../vendor/require/css',
text: '../vendor/require/text',
moment: '../vendor/moment',
filesaver: '../vendor/filesaver',
angular: '../vendor/angular/angular',
'angular-route': '../vendor/angular/angular-route',
'angular-sanitize': '../vendor/angular/angular-sanitize',
'angular-dragdrop': '../vendor/angular/angular-dragdrop',
'angular-strap': '../vendor/angular/angular-strap',
timepicker: '../vendor/angular/timepicker',
datepicker: '../vendor/angular/datepicker',
bindonce: '../vendor/angular/bindonce',
crypto: '../vendor/crypto.min',
spectrum: '../vendor/spectrum',
lodash: 'components/lodash.extended',
'lodash-src': '../vendor/lodash',
bootstrap: '../vendor/bootstrap/bootstrap',
jquery: '../vendor/jquery/jquery-2.1.1.min',
'extend-jquery': 'components/extend-jquery',
'jquery.flot': '../vendor/jquery/jquery.flot',
'jquery.flot.pie': '../vendor/jquery/jquery.flot.pie',
'jquery.flot.events': '../vendor/jquery/jquery.flot.events',
'jquery.flot.selection': '../vendor/jquery/jquery.flot.selection',
'jquery.flot.stack': '../vendor/jquery/jquery.flot.stack',
'jquery.flot.stackpercent':'../vendor/jquery/jquery.flot.stackpercent',
'jquery.flot.time': '../vendor/jquery/jquery.flot.time',
'jquery.flot.crosshair': '../vendor/jquery/jquery.flot.crosshair',
'jquery.flot.fillbelow': '../vendor/jquery/jquery.flot.fillbelow',
modernizr: '../vendor/modernizr-2.6.1',
'bootstrap-tagsinput': '../vendor/tagsinput/bootstrap-tagsinput',
},
shim: {
spectrum: {
deps: ['jquery']
},
crypto: {
exports: 'Crypto'
},
angular: {
deps: ['jquery','config'],
exports: 'angular'
},
bootstrap: {
deps: ['jquery']
},
modernizr: {
exports: 'Modernizr'
},
jquery: {
exports: 'jQuery'
},
// simple dependency declaration
//
'jquery.flot': ['jquery'],
'jquery.flot.pie': ['jquery', 'jquery.flot'],
'jquery.flot.events': ['jquery', 'jquery.flot'],
'jquery.flot.selection':['jquery', 'jquery.flot'],
'jquery.flot.stack': ['jquery', 'jquery.flot'],
'jquery.flot.stackpercent':['jquery', 'jquery.flot'],
'jquery.flot.time': ['jquery', 'jquery.flot'],
'jquery.flot.crosshair':['jquery', 'jquery.flot'],
'jquery.flot.fillbelow':['jquery', 'jquery.flot'],
'angular-dragdrop': ['jquery', 'angular'],
'angular-mocks': ['angular'],
'angular-sanitize': ['angular'],
'angular-route': ['angular'],
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
'bindonce': ['angular'],
timepicker: ['jquery', 'bootstrap'],
datepicker: ['jquery', 'bootstrap'],
'bootstrap-tagsinput': ['jquery'],
},
waitSeconds: 60,
});
...@@ -14,56 +14,41 @@ module.exports = function(grunt) { ...@@ -14,56 +14,41 @@ module.exports = function(grunt) {
'htmlmin:build', 'htmlmin:build',
'ngtemplates', 'ngtemplates',
'cssmin:build', 'cssmin:build',
'build:grafanaVersion',
'ngAnnotate:build', 'ngAnnotate:build',
'requirejs:build', 'requirejs:build',
'concat:js', 'concat:js',
'filerev', 'filerev',
'usemin', 'usemin',
'clean:temp', 'clean:temp',
//'uglify:dest' 'uglify:dest'
]); ]);
grunt.registerTask('build-post-process', function() { grunt.registerTask('build-post-process', function() {
var mode = grunt.config.get('mode'); grunt.config('copy.dist_to_tmp', {
if (mode === 'backend') { expand: true,
grunt.config('copy.dist_to_tmp', { cwd: '<%= destDir %>',
expand: true, src: '**/*',
cwd: '<%= destDir %>', dest: '<%= tempDir %>/public/',
src: '**/*', });
dest: '<%= tempDir %>/public/', grunt.config('clean.dest_dir', ['<%= destDir %>']);
}); grunt.config('copy.backend_bin', {
grunt.config('clean.dest_dir', ['<%= destDir %>']); cwd: 'bin',
grunt.config('copy.backend_bin', { expand: true,
cwd: 'bin', src: ['grafana'],
expand: true, options: { mode: true},
src: ['grafana'], dest: '<%= tempDir %>'
options: { mode: true},
dest: '<%= tempDir %>'
});
grunt.config('copy.backend_files', {
expand: true,
src: ['conf/grafana.ini', 'vendor/**/*', 'scripts/*'],
options: { mode: true},
dest: '<%= tempDir %>'
});
grunt.task.run('copy:dist_to_tmp');
grunt.task.run('clean:dest_dir');
grunt.task.run('copy:backend_bin');
grunt.task.run('copy:backend_files');
}
});
grunt.registerTask('build:grafanaVersion', function() {
grunt.config('string-replace.config', {
files: {
'<%= tempDir %>/app/app.js': '<%= tempDir %>/app/app.js'
},
options: {
replacements: [{ pattern: /@grafanaVersion@/g, replacement: '<%= pkg.version %>' }]
}
}); });
grunt.task.run('string-replace:config'); grunt.config('copy.backend_files', {
expand: true,
src: ['conf/defaults.ini', 'vendor/**/*', 'scripts/*'],
options: { mode: true},
dest: '<%= tempDir %>'
});
grunt.task.run('copy:dist_to_tmp');
grunt.task.run('clean:dest_dir');
grunt.task.run('copy:backend_bin');
grunt.task.run('copy:backend_files');
}); });
}; };
...@@ -38,7 +38,7 @@ module.exports = function(config) { ...@@ -38,7 +38,7 @@ module.exports = function(config) {
}, },
zip_release: { zip_release: {
options: { options: {
archive: '<%= destDir %>/<%= pkg.name %><%= modeOptions.zipSuffix %>-<%= pkg.version %>.zip' archive: '<%= destDir %>/<%= pkg.name %>-<%= pkg.version %>.zip'
}, },
files : [ files : [
{ {
...@@ -56,7 +56,7 @@ module.exports = function(config) { ...@@ -56,7 +56,7 @@ module.exports = function(config) {
}, },
tgz_release: { tgz_release: {
options: { options: {
archive: '<%= destDir %>/<%= pkg.name %><%= modeOptions.zipSuffix %>-<%= pkg.version %>.tar.gz' archive: '<%= destDir %>/<%= pkg.name %>-<%= pkg.version %>.tar.gz'
}, },
files : [ files : [
{ {
......
...@@ -6,9 +6,8 @@ module.exports = function(config,grunt) { ...@@ -6,9 +6,8 @@ module.exports = function(config,grunt) {
var options = { var options = {
appDir: '<%= tempDir %>', appDir: '<%= tempDir %>',
dir: '<%= destDir %>', dir: '<%= destDir %>',
mainConfigFile: '<%= tempDir %>/app/components/require.<%= mode %>.js', mainConfigFile: '<%= tempDir %>/app/components/require.config.js',
baseUrl: './app', baseUrl: './app',
paths: config.modeOptions.requirejs.paths,
modules: [], // populated below, modules: [], // populated below,
...@@ -60,8 +59,7 @@ module.exports = function(config,grunt) { ...@@ -60,8 +59,7 @@ module.exports = function(config,grunt) {
'directives/all', 'directives/all',
'filters/all', 'filters/all',
'controllers/all', 'controllers/all',
'routes/standalone/all', 'routes/all',
'routes/backend/all',
'components/partials', 'components/partials',
] ]
} }
...@@ -76,15 +74,6 @@ module.exports = function(config,grunt) { ...@@ -76,15 +74,6 @@ module.exports = function(config,grunt) {
requireModules[0].include.push('text!panels/'+panelName+'/module.html'); requireModules[0].include.push('text!panels/'+panelName+'/module.html');
}); });
if (config.modeOptions.requirejs.excludeConfig) {
// exclude the literal config definition from all modules
requireModules
.forEach(function (module) {
module.excludeShallow = module.excludeShallow || [];
module.excludeShallow.push('config');
});
}
return { options: options }; return { options: options };
} }
......
...@@ -2,7 +2,7 @@ module.exports = function(config) { ...@@ -2,7 +2,7 @@ module.exports = function(config) {
return { return {
dest: { dest: {
expand: true, expand: true,
src: ['**/*.js', '!config.sample.js', '!app/dashboards/*.js', '!app/dashboards/**/*.js',], src: ['**/*.js', '!dashboards/*.js'],
dest: '<%= destDir %>', dest: '<%= destDir %>',
cwd: '<%= destDir %>', cwd: '<%= destDir %>',
options: { options: {
...@@ -13,4 +13,4 @@ module.exports = function(config) { ...@@ -13,4 +13,4 @@ module.exports = function(config) {
} }
} }
}; };
}; };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment