22 * Portainer functions
33 */
44const axios = require ( 'axios' ) . default ;
5- const fs = require ( 'fs' ) ;
6- const path = require ( 'path' ) ;
75
86/**
97 * Login into portainer
108 * @param {string } username User's username
119 * @param {string } password User's password
12- * @returns {string } JWT token
10+ * @returns {string } Portainer access token
1311 */
1412const login = async function ( username , password ) {
1513 const response = await axios . post ( `${ process . env . PORTAINER_API } /auth` , {
@@ -26,7 +24,7 @@ const login = async function (username, password) {
2624
2725/**
2826 * Get stack descriptor by name
29- * @param {string } token JWT token
27+ * @param {string } token Portainer access token
3028 * @param {string } name Stack name
3129 * @returns {Stack } Stack descriptor
3230 */
@@ -48,15 +46,41 @@ const getStack = async function (token, name) {
4846 return ( response . data && Array . isArray ( response . data ) && response . data . length == 1 ) ? response . data [ 0 ] : null ;
4947}
5048
49+ /**
50+ * Get Stack Docker compose file content
51+ * @param {string } token Portainer access token
52+ * @param {number } stackId
53+ */
54+ const getStackComposeFile = async function ( token , stackId ) {
55+ // Get current stack file
56+ const response = await axios . get ( `${ process . env . PORTAINER_API } /stacks/${ stackId } /file` , {
57+ headers : {
58+ 'Authorization' : `Bearer ${ token } ` ,
59+ } ,
60+ } ) ;
61+
62+ // React to portainer error
63+ if ( response . err )
64+ throw new Error ( response . err ) ;
65+
66+ return response . data . StackFileContent ;
67+ }
68+
5169/**
5270 * Update stack descriptor
53- * @param {string } token
54- * @param {Stack } stack
71+ * @param {string } token Portainer access token
72+ * @param {Stack } stack stack descriptor
73+ * @param {string } composeFile docker compose file contents
5574 */
56- const updateStack = async function ( token , stack ) {
57- const stackfile = await fs . promises . readFile ( path . join ( process . env . PORTAINER_DIR , `${ stack . ProjectPath . replace ( '/data/' , '' ) } /${ stack . EntryPoint } ` ) , 'utf8' ) ;
75+ const updateStack = async function ( token , stack , composeFile = null ) {
76+ if ( ! composeFile )
77+ composeFile = await getStackComposeFile ( token , stack . Id ) ;
78+
79+ if ( ! composeFile || composeFile . trim ( ) . length === 0 )
80+ throw new Error ( 'Docker compose file empty' ) ;
81+
5882 const response = await axios . put ( `${ process . env . PORTAINER_API } /stacks/${ stack . Id } ` , {
59- 'StackFileContent' : stackfile ,
83+ 'StackFileContent' : composeFile ,
6084 'Env' : stack . Env ,
6185 } , {
6286 headers : {
0 commit comments