| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | package renderer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-05-04 15:07:45 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2016-02-16 17:09:26 +08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 19:36:21 +08:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/log" | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/middleware" | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2015-04-08 14:59:12 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type RenderOpts struct { | 
					
						
							| 
									
										
										
										
											2016-09-26 17:07:36 +08:00
										 |  |  | 	Path    string | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 	Width   string | 
					
						
							|  |  |  | 	Height  string | 
					
						
							|  |  |  | 	Timeout string | 
					
						
							|  |  |  | 	OrgId   int64 | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 19:36:21 +08:00
										 |  |  | var rendererLog log.Logger = log.New("png-renderer") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | func RenderToPng(params *RenderOpts) (string, error) { | 
					
						
							| 
									
										
										
										
											2016-09-26 17:07:36 +08:00
										 |  |  | 	rendererLog.Info("Rendering", "path", params.Path) | 
					
						
							| 
									
										
										
										
											2016-02-16 17:09:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var executable = "phantomjs" | 
					
						
							|  |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							|  |  |  | 		executable = executable + ".exe" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-26 17:07:36 +08:00
										 |  |  | 	url := fmt.Sprintf("%s://localhost:%s/%s", setting.Protocol, setting.HttpPort, params.Path) | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-16 17:09:26 +08:00
										 |  |  | 	binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, executable)) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js")) | 
					
						
							| 
									
										
										
										
											2015-04-08 14:59:12 +08:00
										 |  |  | 	pngPath, _ := filepath.Abs(filepath.Join(setting.ImagesDir, util.GetRandomString(20))) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	pngPath = pngPath + ".png" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 	renderKey := middleware.AddRenderAuthKey(params.OrgId) | 
					
						
							|  |  |  | 	defer middleware.RemoveRenderAuthKey(renderKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmdArgs := []string{ | 
					
						
							|  |  |  | 		"--ignore-ssl-errors=true", | 
					
						
							|  |  |  | 		scriptPath, | 
					
						
							| 
									
										
										
										
											2016-09-26 17:07:36 +08:00
										 |  |  | 		"url=" + url, | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 		"width=" + params.Width, | 
					
						
							|  |  |  | 		"height=" + params.Height, | 
					
						
							|  |  |  | 		"png=" + pngPath, | 
					
						
							|  |  |  | 		"domain=" + setting.Domain, | 
					
						
							|  |  |  | 		"renderKey=" + renderKey, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd := exec.Command(binPath, cmdArgs...) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	stdout, err := cmd.StdoutPipe() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	stderr, err := cmd.StderrPipe() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = cmd.Start() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go io.Copy(os.Stdout, stdout) | 
					
						
							|  |  |  | 	go io.Copy(os.Stdout, stderr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	done := make(chan error) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		cmd.Wait() | 
					
						
							|  |  |  | 		close(done) | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-10 23:02:10 +08:00
										 |  |  | 	timeout, err := strconv.Atoi(params.Timeout) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		timeout = 15 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	select { | 
					
						
							| 
									
										
										
										
											2016-03-10 23:02:10 +08:00
										 |  |  | 	case <-time.After(time.Duration(timeout) * time.Second): | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 		if err := cmd.Process.Kill(); err != nil { | 
					
						
							| 
									
										
										
										
											2016-07-30 19:36:21 +08:00
										 |  |  | 			rendererLog.Error("failed to kill", "error", err) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-04 15:07:45 +08:00
										 |  |  | 		return "", fmt.Errorf("PhantomRenderer::renderToPng timeout (>%vs)", timeout) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	case <-done: | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 19:36:21 +08:00
										 |  |  | 	rendererLog.Debug("Image rendered", "path", pngPath) | 
					
						
							| 
									
										
										
										
											2014-10-07 03:31:54 +08:00
										 |  |  | 	return pngPath, nil | 
					
						
							|  |  |  | } |