Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
227b233a
Unverified
Commit
227b233a
authored
Apr 09, 2020
by
Ryan McKinley
Committed by
GitHub
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Toolkit: save a json manifest file for signing (#23446)
parent
692a7387
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
110 additions
and
18 deletions
+110
-18
packages/grafana-toolkit/src/cli/tasks/manifest.test.ts
+42
-2
packages/grafana-toolkit/src/cli/tasks/manifest.ts
+58
-16
packages/grafana-toolkit/src/cli/tasks/plugin/test_exclude_image_suffix_in_manifest.png
+2
-0
packages/grafana-toolkit/src/plugins/types.ts
+8
-0
No files found.
packages/grafana-toolkit/src/cli/tasks/manifest.test.ts
View file @
227b233a
import
{
getFile
Paths
}
from
'./manifest'
;
import
{
getFile
sForManifest
,
convertSha1SumsToManifest
}
from
'./manifest'
;
describe
(
'Manifest'
,
()
=>
{
it
(
'should collect file paths'
,
()
=>
{
const
info
=
getFile
Paths
(
__dirname
);
const
info
=
getFile
sForManifest
(
__dirname
);
expect
(
info
).
toMatchInlineSnapshot
(
`
Array [
"changelog.ts",
...
...
@@ -31,4 +31,44 @@ describe('Manifest', () => {
]
`
);
});
it
(
'should convert a sha1 sum to manifest structure'
,
()
=>
{
const
sha1output
=
`7df059597099bb7dcf25d2a9aedfaf4465f72d8d LICENSE
4ebed28a02dc029719296aa847bffcea8eb5b9ff README.md
4493f107eb175b085f020c1afea04614232dc0fd gfx_sheets_darwin_amd64
d8b05884e3829d1389a9c0e4b79b0aba8c19ca4a gfx_sheets_linux_amd64
88f33db20182e17c72c2823fe3bed87d8c45b0fd gfx_sheets_windows_amd64.exe
e6d8f6704dbe85d5f032d4e8ba44ebc5d4a68c43 img/config-page.png
63d79d0e0f9db21ea168324bd4e180d6892b9d2b img/dashboard.png
7ea6295954b24be55b27320af2074852fb088fa1 img/graph.png
262f2bfddb004c7ce567042e8096f9e033c9b1bd img/query-editor.png
f134ab85caff88b59ea903c5491c6a08c221622f img/sheets.svg
40b8c38cea260caed3cdc01d6e3c1eca483ab5c1 module.js
3c04068eb581f73a262a2081f4adca2edbb14edf module.js.map
bfcae42976f0feca58eed3636655bce51702d3ed plugin.json`
;
const
manifest
=
convertSha1SumsToManifest
(
sha1output
);
expect
(
manifest
).
toMatchInlineSnapshot
(
`
Object {
"files": Object {
"LICENSE": "7df059597099bb7dcf25d2a9aedfaf4465f72d8d",
"README.md": "4ebed28a02dc029719296aa847bffcea8eb5b9ff",
"gfx_sheets_darwin_amd64": "4493f107eb175b085f020c1afea04614232dc0fd",
"gfx_sheets_linux_amd64": "d8b05884e3829d1389a9c0e4b79b0aba8c19ca4a",
"gfx_sheets_windows_amd64.exe": "88f33db20182e17c72c2823fe3bed87d8c45b0fd",
"img/config-page.png": "e6d8f6704dbe85d5f032d4e8ba44ebc5d4a68c43",
"img/dashboard.png": "63d79d0e0f9db21ea168324bd4e180d6892b9d2b",
"img/graph.png": "7ea6295954b24be55b27320af2074852fb088fa1",
"img/query-editor.png": "262f2bfddb004c7ce567042e8096f9e033c9b1bd",
"img/sheets.svg": "f134ab85caff88b59ea903c5491c6a08c221622f",
"module.js": "40b8c38cea260caed3cdc01d6e3c1eca483ab5c1",
"module.js.map": "3c04068eb581f73a262a2081f4adca2edbb14edf",
"plugin.json": "bfcae42976f0feca58eed3636655bce51702d3ed",
},
"plugin": "<?>",
"version": "<?>",
}
`
);
});
});
packages/grafana-toolkit/src/cli/tasks/manifest.ts
View file @
227b233a
...
...
@@ -2,12 +2,13 @@ import { Task, TaskRunner } from './task';
import
fs
from
'fs'
;
import
path
from
'path'
;
import
execa
from
'execa'
;
import
{
ManifestInfo
}
from
'../../plugins/types'
;
interface
ManifestOptions
{
folder
:
string
;
}
export
function
getFile
Paths
(
root
:
string
,
work
?:
string
,
acc
?:
string
[]):
string
[]
{
export
function
getFile
sForManifest
(
root
:
string
,
work
?:
string
,
acc
?:
string
[]):
string
[]
{
if
(
!
acc
)
{
acc
=
[];
}
...
...
@@ -17,37 +18,78 @@ export function getFilePaths(root: string, work?: string, acc?: string[]): strin
const
f
=
path
.
join
(
abs
,
file
);
const
stat
=
fs
.
statSync
(
f
);
if
(
stat
.
isDirectory
())
{
acc
=
getFile
Paths
(
root
,
f
,
acc
);
acc
=
getFile
sForManifest
(
root
,
f
,
acc
);
}
else
{
const
idx
=
f
.
lastIndexOf
(
'.'
);
if
(
idx
>
0
)
{
// Don't hash images
const
suffix
=
f
.
substring
(
idx
+
1
).
toLowerCase
();
if
(
suffix
===
'png'
||
suffix
==
'gif'
||
suffix
===
'svg'
)
{
return
;
}
}
acc
!
.
push
(
f
.
substring
(
root
.
length
+
1
).
replace
(
'
\
\'
, '
/
'));
}
});
return acc;
}
export function convertSha1SumsToManifest(sums: string): ManifestInfo {
const files: Record<string, string> = {};
for (const line of sums.split(/
\
r?
\
n/)) {
const idx = line.indexOf('
');
if (idx > 0) {
const hash = line.substring(0, idx).trim();
const path = line.substring(idx + 1).trim();
files[path] = hash;
}
}
return {
plugin: '
<
?
>
',
version: '
<
?
>
',
files,
};
}
const manifestRunner: TaskRunner<ManifestOptions> = async ({ folder }) => {
const GRAFANA_API_KEY = process.env.GRAFANA_API_KEY;
if (!GRAFANA_API_KEY) {
console.log('
Plugin
signing
requires
a
grafana
API
key
');
}
const filename = '
MANIFEST
.
txt
';
const files = getFile
Paths
(folder).filter(f => f !== filename);
const files = getFile
sForManifest
(folder).filter(f => f !== filename);
// Run sha1sum
const originalDir = __dirname;
process.chdir(folder);
const { stdout } = await execa('
sha1sum
', files);
process.chdir(originalDir);
// Write the process output
fs.writeFileSync(path.join(folder, filename), stdout);
// Send the manifest to grafana API
const manifest = convertSha1SumsToManifest(stdout);
const outputPath = path.join(folder, filename);
// Call a signing service
const GRAFANA_API_KEY = process.env.GRAFANA_API_KEY;
if (GRAFANA_API_KEY) {
const pluginPath = path.join(folder, '
plugin
.
json
');
const plugin = require(pluginPath);
const url = `https://grafana.com/api/plugins/${plugin.id}/sign`;
console.log(`TODO: sign and save: ${url}`);
}
const pluginPath = path.join(folder, '
plugin
.
json
');
const plugin = require(pluginPath);
const url = `https://grafana.com/api/plugins/${plugin.id}/sign`;
manifest.plugin = plugin.id;
manifest.version = plugin.version;
// Go back to where you were
process.chdir(originalDir);
console.log('
Wrote
manifest
:
', filename);
console.log('
Request
Signature
:
', url);
const axios = require('
axios
');
const info = await axios.post(url, manifest, {
headers: { Authorization: '
Bearer
' + GRAFANA_API_KEY },
responseType: '
arraybuffer
',
});
if (info.status === 200) {
console.log('
OK
:
', info.data);
const buffer = new Buffer(info.data, '
binary
');
fs.writeFileSync(outputPath, buffer);
} else {
console.warn('
Error
:
', info);
console.log('
Saving
the
unsigned
manifest
');
fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2));
}
};
export const manifestTask = new Task<ManifestOptions>('
Build
Manifest
', manifestRunner);
packages/grafana-toolkit/src/cli/tasks/plugin/test_exclude_image_suffix_in_manifest.png
0 → 100644
View file @
227b233a
NOTE: not a real image, but should be excluded from hashed files
\ No newline at end of file
packages/grafana-toolkit/src/plugins/types.ts
View file @
227b233a
...
...
@@ -87,3 +87,11 @@ export interface GitLogInfo {
author
:
UserInfo
;
commiter
:
UserInfo
;
}
export
interface
ManifestInfo
{
// time: number; << filled in by the server
// keyId: string; << filled in by the server
plugin
:
string
;
version
:
string
;
files
:
Record
<
string
,
string
>
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment