hostAdminClient.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. const hostAdminURL = Cypress.env('HOST_ADMIN_URL') || 'http://host-admin'
  2. export async function dockerCompose(cmd: string, ...args: string[]) {
  3. return await fetchJSON(`${hostAdminURL}/docker/compose/${cmd}`, {
  4. method: 'POST',
  5. body: JSON.stringify({
  6. args,
  7. }),
  8. })
  9. }
  10. export async function reconfigure({
  11. pro = false,
  12. version = 'latest',
  13. vars = {},
  14. withDataDir = false,
  15. resetData = false,
  16. mongoVersion = '',
  17. }): Promise<{ previousConfigServer: string }> {
  18. return await fetchJSON(`${hostAdminURL}/reconfigure`, {
  19. method: 'POST',
  20. body: JSON.stringify({
  21. pro,
  22. version,
  23. vars,
  24. withDataDir,
  25. resetData,
  26. mongoVersion,
  27. }),
  28. })
  29. }
  30. async function fetchJSON<T = { stdout: string; stderr: string }>(
  31. input: RequestInfo,
  32. init?: RequestInit
  33. ): Promise<T> {
  34. if (init?.body) {
  35. init.headers = { 'Content-Type': 'application/json' }
  36. }
  37. let res
  38. for (let attempt = 0; attempt < 5; attempt++) {
  39. try {
  40. res = await fetch(input, init)
  41. break
  42. } catch {
  43. await sleep(3_000)
  44. }
  45. }
  46. if (!res) {
  47. res = await fetch(input, init)
  48. }
  49. const { error, stdout, stderr, ...rest } = await res.json()
  50. if (error) {
  51. console.error(input, init, 'failed:', error)
  52. if (stdout) console.log(stdout)
  53. if (stderr) console.warn(stderr)
  54. const err = new Error(error.message)
  55. Object.assign(err, error)
  56. throw err
  57. }
  58. return { stdout, stderr, ...rest }
  59. }
  60. export async function runScript({
  61. cwd,
  62. script,
  63. args = [],
  64. user = 'www-data',
  65. hasOverleafEnv = true,
  66. }: {
  67. cwd: string
  68. script: string
  69. args?: string[]
  70. user?: string
  71. hasOverleafEnv?: boolean
  72. }) {
  73. return await fetchJSON(`${hostAdminURL}/run/script`, {
  74. method: 'POST',
  75. body: JSON.stringify({
  76. cwd,
  77. script,
  78. args,
  79. user,
  80. hasOverleafEnv,
  81. }),
  82. })
  83. }
  84. export async function runGruntTask({
  85. task,
  86. args = [],
  87. }: {
  88. task: string
  89. args?: string[]
  90. }) {
  91. return await fetchJSON(`${hostAdminURL}/run/gruntTask`, {
  92. method: 'POST',
  93. body: JSON.stringify({
  94. task,
  95. args,
  96. }),
  97. })
  98. }
  99. export async function getRedisKeys() {
  100. const { stdout } = await fetchJSON(`${hostAdminURL}/redis/keys`, {
  101. method: 'GET',
  102. })
  103. return stdout.split('\n')
  104. }
  105. export async function setMongoFeatureCompatibilityVersion(
  106. mongoVersion: string
  107. ) {
  108. cy.log(`advancing mongo featureCompatibilityVersion to ${mongoVersion}`)
  109. await fetchJSON(`${hostAdminURL}/mongo/setFeatureCompatibilityVersion`, {
  110. method: 'POST',
  111. body: JSON.stringify({
  112. mongoVersion,
  113. }),
  114. })
  115. }
  116. export async function purgeFilestoreData() {
  117. const { stdout } = await fetchJSON(`${hostAdminURL}/data/user_files`, {
  118. method: 'DELETE',
  119. })
  120. if (!stdout.trim()) return []
  121. return stdout.trim().split('\n')
  122. }
  123. async function sleep(ms: number) {
  124. return await new Promise(resolve => {
  125. setTimeout(resolve, ms)
  126. })
  127. }